Skip to content

元数据结构

通用业务开发的第一步是定义元数据结构,元数据结构是用于描述通用业务的数据结构。

新建通用业务

选中通用页面节点,在右侧菜单中点击"添加通用业务"按钮,并根据实际业务场景为其命名。

创建通用业务

创建完成后,对应通用业务下会出现元数据、模版、页面三层结构。

创建通用业务2

其含义如下:

元数据:描述通用业务的数据结构,类似于TypeScriptinterface定义。
typescript
interface IMeta {
    form_query: {
        items: KaceFormItems[];
    }
    table: {
        items: Record<string, any>[];
    }
    form_dialog: {
        items: KaceFormItems[];
    }
    api: {
        query: string;
        update: string;
        delete: string;
        add: string;
    }
}
interface IMeta {
    form_query: {
        items: KaceFormItems[];
    }
    table: {
        items: Record<string, any>[];
    }
    form_dialog: {
        items: KaceFormItems[];
    }
    api: {
        query: string;
        update: string;
        delete: string;
        add: string;
    }
}
模版:通用业务的页面模版,包含样式、变量、事件、方法、渲染组件,是一份低码的元数据结构。
json
{
 "componentName": "kui-b-page",
 "id": 100157,
 "label": "页面",
 "props": {
  "compName": "页面",
  "style": {}
 },
 "events": {},
 "alias": "CURD",
 "componentsTree": [],
 "css": "",
 "lifeCycles": {
  "onMounted": {
   "id": "methodlr4kidik",
   "name": "onMounted",
   "value": " function onMounted () {\nreturn;\n}",
   "props": [],
   "logicList": [
    {
     "id": "logic_onMounted_1704697007845",
     "logicName": "manual",
     "props": {
      "code": "return;"
     }
    }
   ],
   "type": "JSFunction",
   "localVars": [],
   "useScene": "function",
   "label": ""
  }
 },
 "state": {
  "meta": {
   "id": "20be4a33-9805-4699-b56c-b621cb4aead4",
   "value": {
    "new_property_1": {
     "id": "b9fde205-7f7e-4738-8eca-be6d0b6baad7",
     "type": "string",
     "value": ""
    },
    "form_query": {
     "id": "8b403056-3bd6-4afa-ac8a-2b3fe1d13f4e",
     "value": {
      "items": {
       "id": "45598f80-e21f-4e19-bf68-19f5e801b37e",
       "value": [],
       "type": "array"
      }
     },
     "type": "object"
    },
    "table": {
     "id": "f06b81c8-084d-4d99-96d7-6df1ca59872d",
     "value": {
      "items": {
       "id": "3969d1dd-cef6-4732-be54-54811212289d",
       "value": [],
       "type": "array"
      }
     },
     "type": "object"
    },
    "form_dialog": {
     "id": "79970973-6c4b-4702-b1bc-68291a811263",
     "value": {
      "items": {
       "id": "f9c31646-4349-457b-9dd3-2dd7df426aca",
       "value": [],
       "type": "array"
      }
     },
     "type": "object"
    },
    "api": {
     "id": "f209ad70-f827-40d0-bf44-780ed2ab8721",
     "value": {
      "query": {
       "id": "d57119c5-f9d6-4c7d-9e60-891c27c38be3",
       "type": "string",
       "value": ""
      },
      "update": {
       "id": "8a9779db-deb1-46a8-beb6-af32e51536dd",
       "type": "string",
       "value": ""
      },
      "delete": {
       "id": "2fb50f9d-9266-482b-8f8f-a1b1d52a0e73",
       "type": "string",
       "value": ""
      },
      "create": {
       "id": "8b493982-a10c-4578-81f5-f39c3edb17e0",
       "type": "string",
       "value": ""
      }
     },
     "type": "object"
    }
   },
   "type": "object"
  },
  "formModel": {
   "id": "046a1e83-5ba3-4b0b-9308-54dc9480a4bf",
   "type": "object",
   "value": {},
   "desc": ""
  }
 },
 "methods": {},
 "computed": {},
 "emit": {},
 "env": "vue3",
 "permissions": [],
 "watch": [],
 "children": [
  {
   "componentName": "KacePage",
   "id": "node_1001571",
   "label": "page",
   "props": {
    "formModel": {
     "type": "jsExpression",
     "value": "$page.state.formModel",
     "$isBind$": true,
     "mock": {}
    },
    "compName": "page",
    "slot_topBtn": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_otherBtns": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_tableBtnsLeft": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_toolbarRight": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_panel-content": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_default": {
     "enable": false,
     "slotArgName": "scope"
    },
    "formItems": {
     "type": "jsExpression",
     "value": "$page.state.meta.form_query.items",
     "$isBind$": true,
     "mock": ""
    },
    "columns": {
     "type": "jsExpression",
     "value": "$page.state.meta.table.items",
     "$isBind$": true,
     "mock": ""
    },
    "queryUrl": {
     "type": "jsExpression",
     "value": "$page.state.meta.api.query",
     "$isBind$": true,
     "mock": ""
    },
    "style": {}
   },
   "events": {},
   "condition": {
    "v-show": "",
    "v-if": ""
   },
   "ref": ""
  }
 ]
}
{
 "componentName": "kui-b-page",
 "id": 100157,
 "label": "页面",
 "props": {
  "compName": "页面",
  "style": {}
 },
 "events": {},
 "alias": "CURD",
 "componentsTree": [],
 "css": "",
 "lifeCycles": {
  "onMounted": {
   "id": "methodlr4kidik",
   "name": "onMounted",
   "value": " function onMounted () {\nreturn;\n}",
   "props": [],
   "logicList": [
    {
     "id": "logic_onMounted_1704697007845",
     "logicName": "manual",
     "props": {
      "code": "return;"
     }
    }
   ],
   "type": "JSFunction",
   "localVars": [],
   "useScene": "function",
   "label": ""
  }
 },
 "state": {
  "meta": {
   "id": "20be4a33-9805-4699-b56c-b621cb4aead4",
   "value": {
    "new_property_1": {
     "id": "b9fde205-7f7e-4738-8eca-be6d0b6baad7",
     "type": "string",
     "value": ""
    },
    "form_query": {
     "id": "8b403056-3bd6-4afa-ac8a-2b3fe1d13f4e",
     "value": {
      "items": {
       "id": "45598f80-e21f-4e19-bf68-19f5e801b37e",
       "value": [],
       "type": "array"
      }
     },
     "type": "object"
    },
    "table": {
     "id": "f06b81c8-084d-4d99-96d7-6df1ca59872d",
     "value": {
      "items": {
       "id": "3969d1dd-cef6-4732-be54-54811212289d",
       "value": [],
       "type": "array"
      }
     },
     "type": "object"
    },
    "form_dialog": {
     "id": "79970973-6c4b-4702-b1bc-68291a811263",
     "value": {
      "items": {
       "id": "f9c31646-4349-457b-9dd3-2dd7df426aca",
       "value": [],
       "type": "array"
      }
     },
     "type": "object"
    },
    "api": {
     "id": "f209ad70-f827-40d0-bf44-780ed2ab8721",
     "value": {
      "query": {
       "id": "d57119c5-f9d6-4c7d-9e60-891c27c38be3",
       "type": "string",
       "value": ""
      },
      "update": {
       "id": "8a9779db-deb1-46a8-beb6-af32e51536dd",
       "type": "string",
       "value": ""
      },
      "delete": {
       "id": "2fb50f9d-9266-482b-8f8f-a1b1d52a0e73",
       "type": "string",
       "value": ""
      },
      "create": {
       "id": "8b493982-a10c-4578-81f5-f39c3edb17e0",
       "type": "string",
       "value": ""
      }
     },
     "type": "object"
    }
   },
   "type": "object"
  },
  "formModel": {
   "id": "046a1e83-5ba3-4b0b-9308-54dc9480a4bf",
   "type": "object",
   "value": {},
   "desc": ""
  }
 },
 "methods": {},
 "computed": {},
 "emit": {},
 "env": "vue3",
 "permissions": [],
 "watch": [],
 "children": [
  {
   "componentName": "KacePage",
   "id": "node_1001571",
   "label": "page",
   "props": {
    "formModel": {
     "type": "jsExpression",
     "value": "$page.state.formModel",
     "$isBind$": true,
     "mock": {}
    },
    "compName": "page",
    "slot_topBtn": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_otherBtns": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_tableBtnsLeft": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_toolbarRight": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_panel-content": {
     "enable": false,
     "slotArgName": ""
    },
    "slot_default": {
     "enable": false,
     "slotArgName": "scope"
    },
    "formItems": {
     "type": "jsExpression",
     "value": "$page.state.meta.form_query.items",
     "$isBind$": true,
     "mock": ""
    },
    "columns": {
     "type": "jsExpression",
     "value": "$page.state.meta.table.items",
     "$isBind$": true,
     "mock": ""
    },
    "queryUrl": {
     "type": "jsExpression",
     "value": "$page.state.meta.api.query",
     "$isBind$": true,
     "mock": ""
    },
    "style": {}
   },
   "events": {},
   "condition": {
    "v-show": "",
    "v-if": ""
   },
   "ref": ""
  }
 ]
}
页面:描述通用页面具体的页面数据,是一份符合元数据结构定义的JSON数据。
json
{
    "form_query": {
        "items": [
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "结算主体",
                "prop": "settbody",
                "type": "kui-select",
                "required": false,
                "props": {
                    "remote": true,
                    "clearable": true,
                    "options": [],
                    "filterable": true,
                    "labelKey": "settbodyname",
                    "valueKey": "settbody",
                    "remoteMethod": {
                        "type": "jsExpression",
                        "value": "val => {\n        if (val !== \"\") {\n          $global.$http.post('macbs/api/' + \"commSettbodyQueryPage\", {\n            settbody: val,\n            pageSize: 100,\n            pageNum: 1\n          }).then(res => {\n            $page.state.meta.form_query.items.find(val2 => val2.prop === \"settbody\").props.options = res.data;\n          });\n        }\n      }",
                        "url": "macbs/api/commSettbodyQueryPage"
                    }
                }
            }
        ]
    },
    "table": {
        "pageSize": 20,
        "type": "paging",
        "items": [
            {
                "minWidth": 150,
                "__parentType__": "array<object>",
                "prop": "settbody",
                "label": "结算主体"
            },
            {
                "minWidth": 300,
                "__parentType__": "array<object>",
                "prop": "settbodyname",
                "label": "结算主体名"
            },
            {
                "minWidth": 250,
                "__parentType__": "array<object>",
                "prop": "remark",
                "label": "备注"
            }
        ]
    },
    "form_dialog": {
        "items": [
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "结算主体",
                "prop": "settbody",
                "type": "kui-input",
                "required": true,
                "props": {
                    "disabled": false,
                    "maxlength": 32
                }
            },
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "结算主体名",
                "prop": "settbodyname",
                "type": "kui-input",
                "required": true
            },
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "备注",
                "prop": "remark",
                "type": "kui-textarea",
                "required": false,
                "props": {
                    "maxlength": 128,
                    "showWordLimit": true
                }
            }
        ]
    },
    "api": {
        "query": "macbs/api/commSettbodyQueryPage",
        "update": "macbs/api/commSettbodyModify",
        "delete": "macbs/api/commSettbodyRemove",
        "add": "macbs/api/commSettbodyAdd"
    }
}
{
    "form_query": {
        "items": [
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "结算主体",
                "prop": "settbody",
                "type": "kui-select",
                "required": false,
                "props": {
                    "remote": true,
                    "clearable": true,
                    "options": [],
                    "filterable": true,
                    "labelKey": "settbodyname",
                    "valueKey": "settbody",
                    "remoteMethod": {
                        "type": "jsExpression",
                        "value": "val => {\n        if (val !== \"\") {\n          $global.$http.post('macbs/api/' + \"commSettbodyQueryPage\", {\n            settbody: val,\n            pageSize: 100,\n            pageNum: 1\n          }).then(res => {\n            $page.state.meta.form_query.items.find(val2 => val2.prop === \"settbody\").props.options = res.data;\n          });\n        }\n      }",
                        "url": "macbs/api/commSettbodyQueryPage"
                    }
                }
            }
        ]
    },
    "table": {
        "pageSize": 20,
        "type": "paging",
        "items": [
            {
                "minWidth": 150,
                "__parentType__": "array<object>",
                "prop": "settbody",
                "label": "结算主体"
            },
            {
                "minWidth": 300,
                "__parentType__": "array<object>",
                "prop": "settbodyname",
                "label": "结算主体名"
            },
            {
                "minWidth": 250,
                "__parentType__": "array<object>",
                "prop": "remark",
                "label": "备注"
            }
        ]
    },
    "form_dialog": {
        "items": [
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "结算主体",
                "prop": "settbody",
                "type": "kui-input",
                "required": true,
                "props": {
                    "disabled": false,
                    "maxlength": 32
                }
            },
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "结算主体名",
                "prop": "settbodyname",
                "type": "kui-input",
                "required": true
            },
            {
                "__parentType__": "array<kaceFormItems>",
                "label": "备注",
                "prop": "remark",
                "type": "kui-textarea",
                "required": false,
                "props": {
                    "maxlength": 128,
                    "showWordLimit": true
                }
            }
        ]
    },
    "api": {
        "query": "macbs/api/commSettbodyQueryPage",
        "update": "macbs/api/commSettbodyModify",
        "delete": "macbs/api/commSettbodyRemove",
        "add": "macbs/api/commSettbodyAdd"
    }
}

示例:定义元数据结构

考虑一个增删改查场景需要的数据结构,它至少需要如下配置:

  • 搜索区域表单项form_query.items
  • 搜索结果区域的表格列配置table.items
  • 新增/修改弹窗中的表单项form_dialog.items
  • 新增/修改/删除/查询接口地址配置api.create, api.update, api.delete, api.query

在刚才创建的通用业务下双击元数据节点,进入元数据定义页面

创建元数据结构1

在Meta根节点下不断添加下级属性,类型含义可以参考元数据结构类型说明

创建元数据结构2

创建好增删改查场景需要的数据结构,然后点击右上角保存按钮,保存元数据结构信息

创建元数据结构3

至此,就完成了元数据结构的设计。

示例:定义元数据示例

在定义好一份元数据结构之后,点击生成示例按钮,将根据元数据结构创建元数据示例,元数据示例通常在制作模版阶段用于查看设计效果。

创建元数据结构4

在右侧元数据示例中,为搜索表单项、表格配置列添加数据

创建元数据结构4

最后,点击右上角保存按钮,保存元数据示例信息。

对于不同的元数据类型,有不同的输入交互方式:

  • string:使用文本输入框进行输入
  • number:使用数字输入框进行输入
  • boolean:使用Switch切换进行输入
  • function:使用代码编辑器进行输入
  • object:使用JSON编辑器进行输入
  • array<object>:点击"+"图标新增一项,进行输入

如下图示例:

创建元数据结构9

元数据示例管理

通过点击"+"图标创建更多的元数据示例

创建元数据结构5

通过展开示例列表,点击删除图标删除已有的元数据结构示例

创建元数据结构5

表单设计

当字段类型为array<kocaFormItems>array<kaceFormItems>时,提供了一种可视化的方式来设计表单联动信息以及表单字段信息。

设计表单项字段

设计表单字段

点击设计按钮,将弹出右侧抽屉对表单项进行字段设计,将展示表单项实时预览效果、表单配置项、组件配置项。最后点击抽屉下方的确认按钮保存操作。

设计表单项字段

设计表单联动

点击设计按钮,将弹出弹框对表单项进行联动设计。

表单联动是表单配置中核心的一环,目前根据掌握的业务场景,提供了如下四种联动配置方式:

  • 场景1:当表单项A值不为空时,启用表单项B、C 设计表单项字段 设计表单项字段

  • 场景2:当表单项A值为特定值时,隐藏表单项B、C 设计表单项字段 设计表单项字段

  • 场景3:当表单项A的值变化时,执行自定义代码alert(val) 设计表单项字段 设计表单项字段

  • 场景4:当表单项A的值变化时,执行页面方法handleValChange(已在模版中定义此方法体:console.log("入参为", arguments))。设计表单项字段 设计表单项字段

更多联动方式配置会在后续拓展。

元数据结构类型说明

元数据结构中,属性值支持如下的类型:

  • string:字符串类型
  • number:数字类型
  • boolean:布尔值类型
  • function:函数类型
  • object:对象类型,常用
  • array:数组类型,不常用
  • array<kocaFormItems>:koca-ui 表单结构,将自动创建koca-ui组件库表单结构,常用
  • array<kaceFormItems>:kace-ui 表单结构,将自动创建kace-ui组件库表单结构,常用
  • array<object>:对象数组类型,常用
  • array<string>:字符数组类型,不常用
  • array<number>:数字数组类型,不常用
  • array<boolean>:布尔值数组类型,不常用