@Wahson
2017-08-02T09:21:05.000000Z
字数 9606
阅读 1114
bower install git://github.com/mrLeung/front-end-meta.git
TODO:
20. modelSrc传参
任务点:
- 基础组件使用案例,对于每个组件所有特性都应该提供至少一个demo 1d
<h2-tip /><h2-picker /><h2-progress />... 待定- 后端服务测试与对接 3d,周四完成
- datatype:string|object, 支持嵌套结构,{type:string, name: string, unitType} 4h 周五完成
- publish准备,按照要求完善:https://www.webcomponents.org/publish 4h 周五完成
- 文档目录 https://github.com/mrLeung/front-end-meta/blob/master/README.md 1w,下周完成
新的元数据:
// 数据定义// 说明:// 1. [field]? : type => 表示field字段是可选,类型是type// 2. FieldMeta & {prop:value} => 表示FieldMeta扩展了prop属性Model = {[fieldName]: anyactions: array<string>,}dataType: {type: string, primitive|list|set|map|structmetadata: {}unitType: dataType}FieldMeta = {dataType: string, // idl 数据类型, primitive|list|map|set|struct|action,如“i32”、“list”,“TOrder”element?: string, // ui元素,缺省时,会根据datatype和dataTypeExtra,提供默认ui:h2-text|h2-textarea|h2-select-list|h2-radio-group|h2-checkboxname: string, // 字段名,如“orderNo”label: string, // 字段名,如“订单号”require: boolean, // 是否必填,true | falsemutil: boolean, // 多否多选,true | falseformat?: string, // 显示格式,用于日期显示,如“yyyy-MM-dd”editable: boolean, // 是否可编辑,true|falsevalidate: boolean, // 前是否需要校验,true|falselength?: number, // 字符长度maxLength?: number, // 允许最大长度minLength?: number, // 允许最小长度regexp?: string, // 正则匹配prompt? : string, // 校验失败时的提示语,如“请输入备注”min?: number, // 数字最小值max?: number, // 数字最大值placeholder?: string, // placeholdercandidates?: string | function(meta, model), // 候选值,下拉选项中的值,json串,如 "[{value:1,label:'男'},{value:2,label:'女'}]"candidateLabel?: string, // 组件显示字段名,针对下拉组件、radio-group组件等,“label”candidateValue?: string, // 组件值字段名,针对下拉组件、radio-group组件等,“value”alias?: string, // 别名,如果配置了此字段,提交表单时已这个字段作为key保存visible: boolean // 界面是否可见,仅对表单中的字段有效, 默认true}ActionMeta = {actionId: string, // 操作的唯一标识actionName: string, // 操作名,如 “收货”group: string, // 操作组,如 “更多”operType: number, // 操作类型,1:表单,2.弹窗formMeta: FormMeta, // 表单metamodelSrc?: string, // 弹窗的model请求urlmodelQueryParams?: list<string>}GridMeta = {title?: string, // 表格标题,可选grids: [Field & {colspan?: number, // 单元格占多少列rowspan?: number // 单元格占多少行}],actions: { // 按钮操作[actionId]: ActionMeta & {// extended props}}}<h2-grid model={model} gridMeta={gridMeta}></h2-grid>FormMeta = {title: string, // 表单头formUrl: string, // 表单提交的urlhttpMethod: string, // 请求方法 GET | POSTconfirm?: string, // 确认提示isSubmitForbidden,fields: [Field1,Field2,...],}<h2-form model={model} formMeta={formMeta}></h2-form>// h2-domain metadataDomainMeta = {query : {FormMeta & {paging: boolean // 是否需要分页 true|false}},actions: array<Action>,result : GridMeta}
idl表达元数据:
// 数据结构定义struct QueryRequest {1: i32 field1 ( m.ref = "admindb.QueryRequest.field1" )2: optional string field2} (m.ref="admindb.QueryRequest")struct QueryResponse {1: i32 field3 ( m.ref = "metadb.staffs.field3", m.editable="false" ) ,2: optional string field4 ( m.ref = "metadb.staffs.field4", m.editable="false" )3: list<Staffs> staffList ( m.metadata="struct@com.isuwang.soa.admin.service.OrganizationService::1.0.0::Staffs" )4: TStaff aStaff (m.element="h2-action", m.metadata="action@com.isuwang.soa.admin.service.OrganizationService::1.0.0::queryStaffList")}
// 服务接口定义DemoService {QueryResponse query(request: QueryRequest , pageRequest: PageRequest) (m.type="query")void delete(id: Int) (m.type="action",m.id="demo-delete", m.name="删除", m.operType="1", m.modelSrc="" )void add(request: DemoRequest) (m.type="action",m.id="demo-add", m.name="添加", m.operType="2" )}DemoLogisticService {void delete(id: Int) (m.type="action", m.id="demo-logistic-delete", m.name="删除", m.operType="1", m.modelSrc="" )void add(request: DemoLogisticRequest) ( m.type="action", m.id="demo-logistic-add", m.name="添加", m.operType="2" )}// 说明1. m.scope:action的范围,domain | field2. m.ref: 指定字段配置所在的数据库位置,可以配置添加或者覆盖属性值。3. m.type=action:自动根据接口入参和出参,添加formMeta,formMeta中的fields定义来源于入参出参中实体的field定义。m.type = query-action|domain-action|entity-action4. m.permission="" // 此操作需要的权限5. 接口定义约束:6. 接口参数类型:primitive/list/set/map/struct, 如果是struct(默认只有一个struct),
// 元数据查询接口定义MetadataService {Method getMethodDesc( 1: string serviceName 2: string methodName 3: string version )list<Method> getAllMethodsDesc( 1: string serviceName 2: string version )Struct getStructDesc( 1: string serviceName 2: string structName 3: string version )}UIMetaService {/*** 1. foreach(services) => invoke metadataService.getMethods* 2. domainMeta.query = FormMeta( methods.filter(@query).get(0).args )* 3. domainMeta.actions = ActionMeta( methods.filter(@action && @action.scope=='domain' )* 4. domainMeta.result = GridMeta(* grids = list<FieldMeta>( methods.filter(@query).get(0).return ),* actions = ActionMeta( methods.filter(@action && @action.scope=='field' )* )*/DomainMeta getDomainMeta( 1: list<string> services )GridMeta getGridMeta( 1: string serviceName, 2: string methodName )ActionMeta getActionMeta( 1: string serviceName, 2: string methodName )FormMeta getFormMeta( 1: string serviceName, 2: string methodName )}// --------------------------struct FieldMeta {1: i32 id2: string datatype3: ...}struct ActionMeta {1: string actionId: string2: string actionName3: i32 operType4: FormMeta formMeta5: optional string modelSrc}struct FormMeta {1: string title2: string formUrl3: string httpMethod4: optional string confirm5: list<FieldMeta> fields}struct GridMeta {1: list<FieldMeta> grids2: map<string, ActionMeta> actions3: string title}struct DomainMeta {1: FormMeta query2: list<ActionMeta> actions3: GridMeta result}
DROP DATABASEIF EXISTS metadb;CREATE DATABASEIF NOT EXISTS metadb DEFAULT CHARSET utf8 COLLATE utf8_general_ci;DROP TABLE IF EXISTS metadb.fields;CREATE TABLE metadb.fields (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,domain VARCHAR(50) NOT NULL COMMENT '领域,如 "orderdb"',entity VARCHAR(50) NOT NULL COMMENT '实体, 如"Torder"',name VARCHAR(50) NOT NULL COMMENT '字段名,如"orderNo"',alias VARCHAR(50) NULL COMMENT '别名,如"orderNum" ',element VARCHAR(50) NULL COMMENT '替换元素,如 "paper-input" ',label VARCHAR(50) NOT NULL COMMENT '字段名,如"订单号"',required SMALLINT(1) NOT NULL DEFAULT 0 COMMENT '是否必填 1: 是 0:否',mutil SMALLINT(1) NOT NULL DEFAULT 0 COMMENT '多否多选 1: 是 0:否',format VARCHAR(50) NULL COMMENT '显示格式,用于日期显示,如“yyyy-MM-dd”',editable SMALLINT(1) NOT NULL DEFAULT 0 COMMENT '是否可编辑 1: 是 0:否',validate SMALLINT(1) NOT NULL DEFAULT 0 COMMENT '前是否需要校验, 1: 是 0:否',length INT NULL COMMENT '字符允许长度',max_length INT NULL COMMENT '允许最大长度',min_length INT NULL COMMENT '允许最小长度',`regexp` VARCHAR(50) NULL COMMENT '正则匹配',prompt VARCHAR(50) NULL COMMENT '校验失败时的提示语,如“请输入备注”',min INT NULL COMMENT '数字最小值',max INT NULL COMMENT '数字最大值',candidates VARCHAR(1000) NULL COMMENT '下拉选项中的值,json串,如 "[{value:1,label:\'男\'},{value:2,label:\'女\'}]"',candidate_label VARCHAR(50) NULL DEFAULT 'label' COMMENT '组件显示字段名,针对下拉组件、radio-group组件等,“label”',candidate_value VARCHAR(50) NULL DEFAULT 'value' COMMENT '组件值字段名,针对下拉组件、radio-group组件等,“value”',placeholder VARCHAR(50) NULL COMMENT 'placeholder',visible SMALLINT(1) NOT NULL DEFAULT 1 COMMENT '界面是否可见 1: 是 0:否',created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,created_by INT (11) DEFAULT NULL,updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,updated_by INT (11) DEFAULT NULL,UNIQUE field_unique (domain,entity,name) COMMENT '字段唯一约束') COMMENT = '字段元数据';
组件定义的规范和约束:
组件初始化时会自动传入metadata、value和model(model作为context)
组件必须实现以下2个方法,并提供value属性,如果确实没有实现的必要,可以继承H2WidgetBase,该类提供了这三个方法的默认实现。
1. validate()
2. fire 'value-change' event
3. 必要是提供validate失败时的提示。
- 提交表单时,只有visible=true && (required=true || validate=true) 才会触发字段校验
设计点:
- 1. domain's actions: 调整h2-domain,下沉到meta,DomainMeta添加actions配置
- 2. 表单表格嵌套,增加datatype=action
- 3. 复杂单元格支持,页面实现调整
- Field添加render字段,返回一个函数,用户可以定制此函数,render : function(model) { //... return }
- 4. 表格添加筛选条件(查询条件),作为查询组件的一个扩展点,h2-domain-query提供slot
- 5. 单元格简单样式支持,通过扩展支持,钩子函数传递,
- Field添加styler字段,返回一个函数,用户可以定制此函数,styler : function(model) { //... return 'background:red;'}
- 6. 支持表格分页查询,组件支持
- 7. 表单表格数据筛选,组件扩展点实现
- 8. 可编辑表格,h2-grid调整, h2-grid 添加editable属性
已实现组件
下周:
- 1. 员工管理模块达到上线标准
- 2. 图片上传组件
- 3. 订单组件
- 4. 交易员组件
- 5. 供应商组件
- 6. 代理公司组件
- 1. 可编辑表格
- 2. 数据类型组件抽离,支持外部动态添加新组件,已有组件再封装一层,保持取值和重置方法的一致性。
- 3. 元数据组件文档整理
- 4. 元数据下沉到idl
- 5. action添加group特性
- 6. grid layer & 样式调整
- 7. 细化元数据idl,配置下沉到数据库,考虑元数据查询接口设计与实现(queryMeta)
- 8. react.render实验
例子:
GridMeta = {grids: [{datatype: "text",name: "orderNo",label: "订单号",required: true,mutil: false,},{datatype: "date",name: "createAt",label: "创建时间",required: true,mutil: false,format: 'yyyy-MM-dd'}],actions: {"order-cancel": {actionId: "order-cancel",actionName: "取消",operType: 1,formMeta: {formUrl: "/order/cancelOrder.do",httpMethod: "GET",fields: [{datatype: "text",name: "orderId",label: "订单Id",required: true,mutil: false,},],}},"new-order-item": {actionId: "new-order-item",actionName: "新子单",operType: 2,formMeta: {formUrl: "/order/saveOrderItem.do", // 表单提交的urlhttpMethod: "POST",fields: [{datatype: "text",name: "orderId",label: "订单Id",required: true,mutil: false,},{datatype: "select",name: "product",label: "产品",required: true,mutil: false,displayField: "productName",valueField: "productId",itemsField: "products",prompt: "请选产品"},{datatype: "text",name: "product",label: "备注",required: false,mutil: false,validate:true,max-length: 100}],}}}}model = {products:[{productId: "123",productName: ""}]}FormMeta = {formUrl: "cancelOrder", // 表单提交的urlhttpMethod: "GET", // 请求方法 GET | POSTfields: [{datatype: "text",name: "orderId",label: "订单Id",required: true,mutil: false,}],}// h2-domain metadataDomainMeta = {query : {FormMeta & {paging: boolean // 是否需要分页 true|false}},result : GridMeta}
组件数据类型定义
datatype = 类型(可选项)
- 1. string (length, max-length, min-length, regexp) // value是字符串
- 2. number ( max, min ) // value是数字
- 3. date ( max, min , format ) // value是日期的长整型
- 4. select ( multi, displayField, valueField,itemsField ) // value是当前选中的值 1,[1,2]
- 5. radio ( displayField, valueField ,itemsField ) // value是当前选中的值
- 6. grid ( theads ) // value是表格的二维数组
// 业务组件- 7. order-picker( displayField,valueField )
- 8. purchase-order-picker( displayField,valueField )
- 9. staff-picker( displayField,valueField )
- 10. action ( actionMeta ) //
- 11.