数据表格 
1. 命名规范 
数据表格描述文件是以 小写英文字母 命名的 JSON 文本文件 <name>.tab.json
| 文件夹 (相对应用模型根目录) | 文件名 | 表格名称 | API 路由地址 | 
|---|---|---|---|
| / | name.tab.json | name | /api/xiang/table/name/管理接口 | 
| /group/ | name.tab.json | gorup.name | /api/xiang/table/group.name/管理接口 | 
| /group1/group2/ | name.tab.json | gorup1.gorup2.name | /api/xiang/table/group1.group2.name/管理接口 | 
2. 文档结构 
数据表格文档,由表格基础信息、数据模型绑定、业务结构映射表、字段映射表、过滤器映射表、列表页、编辑页、批量插入页和详情页构成。
{
  "name": "云服务库",
  "version": "1.0.0",
  "bind": {},
  "apis": {},
  "columns": {},
  "filters": {},
  "list": {},
  "edit": {},
  "view": {},
  "insert": {}
}| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| name | String | 数据表格名称 | 是 | 
| version | String | 版本号,用于依赖关系校验和开发平台呈现 | 是 | 
| bind | Object Bind | 绑定数据模型。 | 否 | 
| hooks | [key:String]:String | 数据表格 Hook | 否 | 
| apis | [key:String]:Object API | 数据管理 API 设置。如设置绑定数据模型,自动根据模型信息生成数据管理 API, 可通过设置同 key 的配置信息,覆盖自动生成的 API。 | 否 | 
| columns | [key:String]:Object Column | 字段呈现方式设置。 如设置绑定数据模型,自动根据字段类型信息设置关联组件,可通过设置同 key 的配置信息,覆盖自动生成的关联组件信息。 | 否 | 
| filters | [key:String]:Object Filter | 查询过滤器设置。 如设置绑定数据模型,自动根据索引和字段信息设置关联组件,可通过设置同 key 的配置信息,覆盖自动生成的关联组件信息。 | 否 | 
| list | Object Page | 列表页设置。 | 是 | 
| edit | Object Page | 编辑页设置。 | 是 | 
| view | Object Page | 查看页设置。 | 否 | 
| insert | Object Page | 批量录入页设置。 | 否 | 
2.1 基础信息 
{
  "name": "用户",
  "title": "可信云云服务库 | 数据管理",
  "decription": "可信云云服务库"
}| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| name | String | 数据表格名称, 可用于开发平台中呈现 | 是 | 
| title | String | 打开数据表格页面时,浏览器栏呈现的页面标题 | 否 | 
| decription | String | 数据表格介绍, 可用于开发平台中呈现 | 否 | 
2.2 绑定数据模型 bind 
可以通过设置 model 和 withs, 实现数据表格与数据模型绑定。绑定后,应用引擎将根据数据模型定义,生成 apis, columns 和 fliters 配置,如需要特殊声明,添加同 key 的特殊配置信息即可。也可在 columns, fliters 新增字段用于各页面呈现。
{
  "bind": {
    "model": "service",
    "withs": {
      "manu": {
        "query": {
          "select": ["id", "name", "short_name", "status"]
        }
      },
      "kind": {
        "query": {
          "select": ["id", "name"]
        }
      }
    }
  }
}| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| model | String | 绑定数据模型名称 | 是 | 
| withs | [key:String]:Object With | 数据模型关联查询设置. | 否 | 
2.3 数据表格管理接口 apis 
数据表格将提供增删改查等接口,通过这些接口完成数据管理操作。如设置绑定数据模型,自动根据模型信息生成数据管理 API, 可通过设置同 key 的配置信息,覆盖自动生成的 API, API 输入输出数据结构需与原接口保持一致。
Object API 数据结构 
{
  "apis": {
    "search": {
      "process": "models.service.Paginate",
      "guard": "bearer-jwt",
      "default": [
        {
          "withs": {
            "manu": {
              "query": {
                "select": ["id", "name", "short_name", "status"]
              }
            }
          }
        },
        null,
        15
      ]
    },
    "find": {
      "process": "models.service.Find",
      "default": [
        null,
        {
          "withs": {
            "manu": {
              "query": {
                "select": ["id", "name", "short_name", "status"]
              }
            }
          }
        }
      ]
    },
    "管理接口(key) ": {
      "process": "处理器名称",
      "guard": "-",
      "default": []
    }
  }
}| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| process | String | 绑定处理器 (process) 输入输出数据结构需与原接口保持一致 | 是 | 
| guard | String | 接口鉴权中间件, 多个用 , 分割, 设置为 - 不设置鉴权中间件, 不设置继承默认鉴权方式。 | 否 | 
| default | Array<Any> | 参数表默认值, 如没有默认值可以设置为 null, 如 [null, null, 15] | 否 | 
接口列表 
管理接口(key) | 请求方式 | 路由(相对) | 说明 | 
|---|---|---|---|
| search | GET | /search | 按条件查询, 分页。 | 
| find | GET | /find | 按主键查询单条记录。 | 
| save | POST | /save | 保存单条记录,存在更新,不存在创建。 | 
| delete | POST | /delete | 按主键删除单条记录。 | 
| insert | POST | /insert | 批量新增记录。 | 
| delete-where | POST | /delete/where | 批量删除符合条件的记录。 | 
| delete-in | POST | /delete/in | 批量删除指定一组主键的的数据记录。 | 
| update-where | POST | /update/where | 批量更新符合条件的记录。 | 
| update-in | POST | /update/in | 批量更新指定一组主键的的数据记录。 | 
| quicksave | POST | /quicksave | 保存多条记录,存在更新,不存在创建。 | 
| setting | GET | /setting | 读取数据表格配置信息, 用于前端界面渲染 | 
2.4 字段呈现方式 columns 
可以对字段设定在列表呈现 (view)、列表编辑 (edit)和编辑表单(form)中的呈现方式, 字段自由添加,可在各页面呈现设置中使用。如设置绑定数据模型,自动根据数据模型字段名称、字段类型生成对应呈现, 可通过设置同 key 的配置信息,覆盖自动生成的呈现信息。字段呈现方式映射表,可从 setting 接口中读取。
{
  "columns": {
    "name": {
      "label": "服务名称",
      "view": {
        "type": "label",
        "props": {
          "value": ":name"
        }
      },
      "edit": {
        "type": "input",
        "props": {
          "value": ":name"
        }
      },
      "form": {
        "type": "input",
        "props": {
          "value": ":name"
        }
      }
    },
    "manu.name": {
      "label": "厂商名称",
      "view": {
        "type": "label",
        "props": {
          "value": ":manu.name"
        }
      }
    },
    "所属厂商": {
      "label": "所属厂商",
      "view": {
        "name": "label",
        "props": {
          "value": ":manu.short_name"
        }
      },
      "edit": {
        "type": "select",
        "props": {
          "value": ":manu.id",
          "searchable": true,
          "remote": {
            "api": "/api/manu/get",
            "query": {
              "select": ["id", "name"],
              "keyword": "where_name_like"
            }
          }
        }
      }
    }
  }
}Object Column 数据结构 
| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| label | String | 字段呈现的字段名称 | 是 | 
| view | Object Render | 列表或查看页面,阅读状态时的使用的组件及属性, 默认为 label | 否 | 
| edit | Object Render | 列表或查看页面,编辑状态时的使用的组件及属性 , 默认为 input | 否 | 
| form | Object Render | 编辑页面,使用的组件及属性,默认为 input | 否 | 
2.5 查询过滤器 fliters 
可以通过设置查询过滤器,添加数据查询条件呈现。 查询过滤器自由添加,可在列表页面呈现设置中使用。如设置绑定数据模型,自动根据数据模型索引名称、字段信息生成对应配置, 可通过设置同 key 的配置信息,覆盖自动生成的配置信息。查询过滤器映射表,可从 setting 接口中读取。
{
  "filters": {
    "关键词": {
      "label": "关键词",
      "bind": "where.name.like",
      "input": {
        "type": "input",
        "props": {
          "placeholder": "请输入关键词"
        }
      }
    },
    "所属厂商": {
      "label": "厂商",
      "bind": "where.manu_id.in",
      "input": {
        "type": "select",
        "props": {
          "searchable": true,
          "multiple": true,
          "placeholder": "请选择所属厂商",
          "remote": {
            "api": "/api/manu/get",
            "query": {
              "select": ["id", "name"],
              "keyword": "where.name.like",
              "limit": 500
            }
          }
        }
      }
    }
  }
}Object Filter 数据结构 
| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| label | String | 过滤器显示名称 | 是 | 
| bind | String | 绑定的查询条件 URL Query String 字段名称, 如 where.manu_id.in (用作 search API 查询参数) | 是 | 
| input | Object Render | 查询内容输入组件, 默认为 input | 否 | 
2.6 列表页 list 
{
  "list": {
    "primary": "id",
    "layout": {
      "columns": [
        { "name": "服务名称", "width": 6 },
        { "name": "所属厂商", "width": 6 },
        { "name": "服务类型", "width": 4 }
      ],
      "filters": [
        { "name": "关键词", "width": 6 },
        { "name": "所属厂商", "width": 6 }
      ]
    },
    "actions": {
      "create": {
        "type": "button",
        "props": {
          "label": "新建服务"
        }
      },
      "view": {},
      "edit": {},
      "import": {},
      "update": {},
      "delete": {},
      "insert": {},
      "updateWhere": {},
      "deleteWhere": {},
      "updateSelect": {},
      "deleteSelect": {},
      "pagination": {
        "type": "",
        "props": {
          "pages": true,
          "prev": true,
          "next": true
        }
      },
      "setting": {}
    }
  }
}布局 (layout) 
| 字段 | 类型 | 说明 | 
|---|---|---|
columns | Array<Object ColumnInstance | String > | 数据列表可呈现的列 | 
filters | Array<Object FilterInstance | String > | 可呈现的查询过滤器 | 
Object ColumnInstance 数据结构 
| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| name | String | 字段名称。必须已在字段呈现方式(columns)中定义。 | 是 | 
| width | Integer | 列宽度。使用栅格系统,有效值 1-24。默认值为 6 | 否 | 
Object FilterInstance 数据结构 
| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| name | String | 字段名称。必须已在查询过滤器方式(filters)中定义。 | 是 | 
| width | Integer | 列宽度。使用栅格系统,有效值 1-24。默认值为 6 | 否 | 
功能 (actions) 
| 名称 | 说明 | 
|---|---|
create | 新建数据记录按钮 | 
view | 查看数据记录详情按钮 | 
edit | 修改数据记录表单按钮 | 
import | 导入数据记录按钮 | 
export | 导出数据记录按钮 | 
update | 更新单条字段按钮 | 
delete | 删除单条记录按钮 | 
insert | 批量插入按钮 | 
deleteWhere | 按条件批量删除按钮 | 
updateWhere | 按条件批量更新按钮 | 
deleteSelect | 批量删除选中数据记录按钮 | 
updateSelect | 批量更新选中数据记录按钮 | 
pagination | 分页器 | 
setting | 数据表配置按钮 | 
2.7 编辑页 edit 
{
  "edit": {
    "primary": "id",
    "layout": {
      "groups": [
        {
          "title": "基础信息",
          "description": "",
          "columns": [
            { "name": "服务名称", "width": 6 },
            { "name": "所属厂商", "width": 6 },
            { "name": "服务类型", "width": 6 },
            { "name": "状态", "width": 6 },
            { "name": "rank", "width": 6 }
          ]
        },
        {
          "title": "数据标签",
          "description": "",
          "columns": ["服务领域", "计费方式", "行业覆盖"]
        }
      ]
    },
    "actions": {
      "cancel": {},
      "save": {
        "type": "button",
        "props": {
          "label": "保存"
        }
      },
      "delete": {}
    }
  }
}布局 (layout) 
| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
groups | Array<Object Group> | 编辑表单字段分组列表 | 是 | 
Object Group 数据结构
| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
title | String | 分组名称 | 否 | 
description | String | 分组介绍 | 否 | 
columns | Array<Object ColumnInstance | String > | 数据列表可呈现的列 | 是 | 
功能 (actions) 
| 名称 | 说明 | 
|---|---|
cancel | 取消编辑按钮 | 
save | 保存数据按钮 | 
delete | 删除数据按钮 | 
2.8 查看页 view 
本版不做实现
2.9 批量录入页 insert 
本版不做实现
3. Object Render 数据结构 
{
  "type": "select",
  "props": {
    "value": "{{manu_id}}",
    "searchable": true,
    "remote": {
      "api": "/api/manu/get",
      "query": {
        "select": ["id", "name"],
        "keyword": "where.name.like"
      }
    }
  }
}| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| type | String | 使用的组件名称 | 是 | 
| props | Object<Any> | 组件属性,具体查看对应组件文档。属性参数中可以使用 字符串、数字 和 变量。 | 否 | 
| components | Array<Any> | 复合组件,引用原子组件名称或描述。 ["计费方式", "行业覆盖", {"name":"姓名", "props":{}}] | 否 | 
在属性(props) 中使用变量
可以在属性(props)中可以使用 {{字段名称}} 或 :字段名称 引用当前记录数据,支持使用 . 访问 Object 或 Array 类型数据,如 {{字段名称.foo.bar}}、{{字段名称.0.foo}}、:字段名称.foo.bar、:字段名称.0.foo
4. Object Page 数据结构 
{
  "edit": {
    "primary": "id",
    "layout": {
      "groups": [
        {
          "title": "数据标签",
          "description": "",
          "columns": ["服务领域", "计费方式", "行业覆盖"]
        }
      ]
    },
    "actions": {
      "cancel": {},
      "save": {
        "type": "button",
        "props": {
          "label": "保存"
        }
      },
      "delete": {}
    }
  }
}| 字段 | 类型 | 说明 | 必填项 | 
|---|---|---|---|
| primary | String | 主键字段名称 | 是 | 
| layout | [key:String]:Any | 页面布局可选配置项,每个页面不同,在具体页面中定义。 | 是 | 
| actions | [key:String]:[key:String]:Object Render | 页面可用功能呈现方式映射表,每个页面不同,在具体页面中定义。 | 否 | 
| option | [key:String]:Any | 页面配置信息,根据需要自由定义。API Setting 原样返回。 | 否 | 
5. 完整示例 
完整示例保存在 examples 目录
{
  "name": "云服务库",
  "version": "1.0.0",
  "decription": "可信云云服务库",
  "bind": {
    "model": "service",
    "withs": {
      "manu": {
        "query": {
          "select": ["id", "name", "short_name", "status"]
        }
      },
      "kind": {
        "query": {
          "select": ["id", "name"]
        }
      }
    }
  },
  "apis": {
    "search": {
      "process": "models.service.Paginate",
      "default": [
        {
          "withs": {
            "manu": {
              "query": {
                "select": ["id", "name", "short_name", "status"]
              }
            },
            "kind": {
              "query": {
                "select": ["id", "name"]
              }
            }
          },
          "wheres": [{ "column": "status", "value": "enabled" }]
        },
        null,
        15
      ]
    },
    "find": {
      "process": "models.service.Find",
      "default": [
        null,
        {
          "withs": {
            "manu": {
              "query": {
                "select": ["id", "name", "short_name", "status"]
              }
            },
            "kind": {
              "query": {
                "select": ["id", "name"]
              }
            }
          }
        }
      ]
    }
  },
  "columns": {
    "服务名称": {
      "label": "服务名称",
      "view": {
        "type": "label",
        "props": {
          "value": ":name"
        }
      },
      "edit": {
        "type": "input",
        "props": {
          "value": ":name"
        }
      }
    },
    "所属厂商": {
      "label": "所属厂商",
      "view": {
        "name": "label",
        "props": {
          "value": ":manu.short_name"
        }
      },
      "edit": {
        "type": "select",
        "props": {
          "value": ":manu.id",
          "searchable": true,
          "remote": {
            "api": "/api/manu/get",
            "query": {
              "select": ["id", "name"],
              "keyword": "where_name_like"
            }
          }
        }
      }
    },
    "服务类型": {
      "label": "服务类型",
      "view": {
        "name": "label",
        "props": {
          "value": ":kind.name"
        }
      },
      "edit": {
        "type": "select",
        "props": {
          "value": ":kind.id",
          "tree": true,
          "searchable": true,
          "remote": {
            "api": "/api/kind/tree",
            "query": {
              "select": ["id", "name"],
              "keyword": "where_name_like"
            }
          }
        }
      }
    },
    "服务领域": {
      "label": "服务领域",
      "view": {
        "name": "tags",
        "props": {
          "value": ":fields"
        }
      },
      "edit": {
        "type": "select",
        "props": {
          "value": ":fields",
          "searchable": true,
          "inputable": true,
          "multiple": true,
          "options": [
            { "label": "视频会议", "value": "视频会议" },
            { "label": "即时通信", "value": "即时通信" },
            { "label": "客服管理", "value": "客服管理" },
            { "label": "财务管理", "value": "财务管理" },
            { "label": "客户关系管理", "value": "客户关系管理" },
            { "label": "营销管理", "value": "营销管理" },
            { "label": "办公自动化", "value": "办公自动化" },
            { "label": "ERP", "value": "ERP" },
            { "label": "人力", "value": "人力" },
            { "label": "采购", "value": "采购" },
            { "label": "供应链", "value": "供应链" },
            { "label": "企业网盘", "value": "企业网盘" },
            { "label": "邮件服务", "value": "邮件服务" },
            { "label": "电子合同", "value": "电子合同" },
            { "label": "安全工具", "value": "安全工具" },
            { "label": "舆情分析", "value": "舆情分析" },
            { "label": "行业应用", "value": "行业应用" },
            { "label": "其他", "value": "其他" }
          ]
        }
      }
    },
    "计费方式": {
      "label": "计费方式",
      "view": {
        "name": "tags",
        "props": {
          "value": ":fields"
        }
      },
      "edit": {
        "type": "select",
        "props": {
          "value": ":price_options",
          "multiple": true,
          "options": [
            { "label": "按年订阅", "value": "按年订阅" },
            { "label": "按月订阅", "value": "按月订阅" },
            { "label": "按量计费", "value": "按量计费" },
            { "label": "私有化部署", "value": "私有化部署" },
            { "label": "其他", "value": "其他" }
          ]
        }
      }
    },
    "行业覆盖": {
      "label": "行业覆盖",
      "view": {
        "name": "tags",
        "props": {
          "value": ":industries"
        }
      },
      "edit": {
        "type": "select",
        "props": {
          "value": ":industries",
          "inputable": true,
          "multiple": true,
          "options": [
            { "label": "房地产", "value": "房地产" },
            { "label": "旅游", "value": "旅游" },
            { "label": "教育", "value": "教育" },
            { "label": "互联网", "value": "互联网" },
            { "label": "其他", "value": "其他" }
          ]
        }
      }
    },
    "状态": {
      "label": "状态",
      "view": {
        "name": "tags",
        "props": {
          "value": ":status",
          "options": [
            { "label": "开启", "value": "enabled", "color": "primary" },
            { "label": "关闭", "value": "disabled", "color": "danger" }
          ]
        }
      },
      "edit": {
        "type": "select",
        "props": {
          "value": ":status",
          "options": [
            { "label": "开启", "value": "enabled" },
            { "label": "关闭", "value": "disabled" }
          ]
        }
      }
    },
    "创建时间": {
      "label": "创建时间",
      "view": {
        "name": "label",
        "props": {
          "value": ":created_at",
          "datetime-format": "YYYY年MM月DD日 @hh:mm:ss"
        }
      }
    },
    "更新时间": {
      "label": "更新时间",
      "view": {
        "name": "label",
        "props": {
          "value": ":update_at",
          "datetime-format": "YYYY年MM月DD日 @hh:mm:ss"
        }
      }
    },
    "查询排序": {
      "label": "查询排序",
      "view": {
        "type": "label",
        "props": {
          "value": ":rank"
        }
      },
      "edit": {
        "type": "input",
        "props": {
          "value": ":rank",
          "type": "number"
        }
      }
    }
  },
  "filters": {
    "关键词": {
      "label": "关键词",
      "bind": "where.name.like",
      "input": {
        "type": "input",
        "props": {
          "placeholder": "请输入关键词"
        }
      }
    },
    "所属厂商": {
      "label": "厂商",
      "bind": "where.manu_id.in",
      "input": {
        "type": "select",
        "props": {
          "searchable": true,
          "multiple": true,
          "placeholder": "请选择所属厂商",
          "remote": {
            "api": "/api/manu/get",
            "query": {
              "select": ["id", "name"],
              "keyword": "where_name_like"
            }
          }
        }
      }
    },
    "服务类型": {
      "label": "类型",
      "bind": "where.kind_id.in",
      "input": {
        "type": "select",
        "props": {
          "tree": true,
          "searchable": true,
          "multiple": true,
          "placeholder": "请选择所属类型",
          "remote": {
            "api": "/api/kind/tree",
            "query": {
              "select": ["id", "name"],
              "keyword": "where_name_like"
            }
          }
        }
      }
    }
  },
  "list": {
    "primary": "id",
    "layout": {
      "columns": [
        { "name": "服务名称", "width": 6 },
        { "name": "所属厂商", "width": 6 },
        { "name": "服务类型", "width": 4 },
        { "name": "状态", "width": 4 },
        { "name": "服务领域", "width": 4 },
        { "name": "计费方式", "width": 4 },
        { "name": "创建时间", "width": 6 },
        { "name": "更新时间", "width": 6 }
      ],
      "filters": [
        { "name": "关键词", "width": 6 },
        { "name": "所属厂商", "width": 6 },
        { "name": "服务类型", "width": 4 }
      ]
    },
    "actions": {
      "create": {
        "type": "button",
        "props": {
          "label": "新建服务",
          "icon": "fas fa-plus"
        }
      },
      "view": {},
      "edit": {},
      "import": {},
      "update": {},
      "delete": {},
      "insert": {},
      "updateWhere": {},
      "deleteWhere": {},
      "updateSelect": {},
      "deleteSelect": {},
      "pagination": ["pages", "prev", "next"],
      "setting": {}
    }
  },
  "edit": {
    "primary": "id",
    "layout": {
      "fieldset": [
        {
          "title": "基础信息",
          "description": "",
          "columns": [
            { "name": "服务名称", "width": 6 },
            { "name": "所属厂商", "width": 6 },
            { "name": "服务类型", "width": 6 },
            { "name": "状态", "width": 6 },
            { "name": "rank", "width": 6 }
          ]
        },
        {
          "title": "数据标签",
          "description": "",
          "columns": ["服务领域", "计费方式", "行业覆盖"]
        }
      ]
    },
    "actions": {
      "cancel": {},
      "save": {
        "type": "button",
        "props": {
          "label": "保存"
        }
      },
      "delete": {}
    }
  },
  "insert": {},
  "view": {}
}