前言
领域驱动设计(简称 ddd)概念来源于2004年著名建模专家Eric Evans 发表的他最具影响力的书籍:《领域驱动设计——软件核心复杂性应对之道》(Domain-Driven Design –Tackling Complexity in the Heart of Software),简称Evans DDD,领域驱动设计思想进入软件开发者的视野。在将近20年的发展中领域模型设计一直占据着非常重要的位置,但其直接面向业务场景的设计思想,更适合在具有特定业务场景的模型构建。在日常我们见到的DDD模型多数是具有特定业务背景的特定业务(Domain-Specific Modeling)特定领域建模工具。
近两年,随着新一代WEB技术以及,微服务、中台技术,云原生应用的推广;领域驱动模型(DDD)再次成为软件设计领域的热点。 而低代码/无代码平台是进近几年持续高速发展的一个技术领域。
一,OneCode-工具集 简介
OneCode-DSM(以下简称DSM)工具集是建立是以OneCode低代码引擎为基础专注于低代码建模应用的高阶建模工具。
在OneCode引擎中,出了为普通用户提供无代码的拖动设计器,低代码的业务逻辑编排器,之外还提供了供专业业务领域专家的使用的DSM建模工具。
编辑切换为居中
OneCode-DSM 应用
(1)可视化设计器
以可视化设计器引擎为主体的表单报表工具,在日常常用的表单报表中是以无代码的方式来实现业务流审批以及数据大屏展现设计,移动展现等应用。
编辑切换为居中
添加图片注释,不超过 140 字(可选)
(2)低代码服务集成工具
编辑切换为居中
添加图片注释,不超过 140 字(可选)
(3)DSM建模工具
编辑切换为居中
添加图片注释,不超过 140 字(可选)
二,OneCode-DSM工具
(1)工具组成概览
DSM建模工具是OneCode建模的辅助工具,提供了资源库管理模块,领域模型构建模块,以及视图工厂配置模块。
编辑切换为居中
添加图片注释,不超过 140 字(可选)
仓储模型模块,主要功能是辅助用户将用户的数据库,外部API接口,以及已有的“代码”应用通过转换器转变为可被DSM识别的资源部格式。
领域模型模块是DSM核心工具,在领域模型中导入的资源会同具体场景下的值对象,场景菜单、通用域服务根据具体的业务场景完成领域模型的建模工作。
视图工厂是领域模型的具体实现,在领域模型应用中建模输出的产物会通过出码工厂输出位视图应用,这些视图应用会通过视图工厂进一步加工处理输出为用户交互应用。
(2)OneCode语言(注解)组成
编辑切换为居中
添加图片注释,不超过 140 字(可选)
(3)建模流程
编辑切换为居中
添加图片注释,不超过 140 字(可选)
三,仓储库建模
编辑切换为居中
添加图片注释,不超过 140 字(可选)
(1)通过数据库建模
仓储工具中使用频率最高的是数据库的转换应用,用户通过数据库工具完成数据源配置。
编辑切换为居中
数据源配置
库表映射代码示例:
@DBTable(configKey="fdt",cname="领导信息",tableName="FDT_LINGDAO",primaryKey="uuid")@Repository(repositoryId="54fa1fd2-cae4-44b0-8387-f10f98bdd63c")publicinterfaceFdtLingdao { @Uid @DBField(cnName="主键",dbFieldName="uuid")publicStringgetUuid(); publicvoidsetUuid(String uuid); @CustomAnnotation(caption="名称") @DBField(cnName="名称",length=20,dbFieldName="test") publicStringgetTest(); publicvoidsetTest(String test); @CustomAnnotation(caption="领导姓名") @DBField(cnName="领导姓名",length=20,dbFieldName="name") publicStringgetName(); publicvoidsetName(String name); @CustomAnnotation(caption="职务") @DBField(cnName="职务",length=100,dbFieldName="duty") publicStringgetDuty(); publicvoidsetDuty(String duty); @CustomAnnotation(caption="创建时间") @DBField(cnName="创建时间",length=0,dbType=ColType.DATETIME,dbFieldName="createtime") publicDategetCreatetime(); publicvoidsetCreatetime(Date createtime); }
库表装载器CRUD代码示例:
@Aggregation(type =AggregationType.aggregationEntity,entityClass=FdtLingdao.class,rootClass=FdtLingdaoService.class)publicinterfaceFdtLingdaoService { @APIEventAnnotation(bindMenu ={CustomMenuItem.reload}) publicList<FdtLingdao>findAll()throwsJDSException; publicList<FdtLingdao>findByWhere(String where)throwsJDSException; @APIEventAnnotation(bindMenu ={CustomMenuItem.search}) publicList<FdtLingdao>find(FdtLingdao fdtLingdao)throwsJDSException; @APIEventAnnotation(bindMenu ={CustomMenuItem.add,CustomMenuItem.editor}) publicFdtLingdaogetFdtLingdaoInfo(String uuid)throwsJDSException; @APIEventAnnotation(bindMenu ={CustomMenuItem.save}, callback ={CustomCallBack.ReloadParent,CustomCallBack.Close}) publicFdtLingdaoupdate(FdtLingdao fdtLingdao)throwsJDSException; @APIEventAnnotation(bindMenu ={CustomMenuItem.delete}, callback ={CustomCallBack.Reload}) publicBooleandelete(String uuid)throwsJDSException;}
(2)通过实体建模
仓储实体实例
编辑切换为居中
添加图片注释,不超过 140 字(可选)
@Entity@Aggregation(type =AggregationType.aggregationRoot,sourceClass =Role.class, rootClass =Role.class)publicinterfaceRoleextends java.io.Serializable{ @MethodChinaName(cname ="角色标识") @Uid publicStringgetRoleId(); publicvoidsetRoleId(String roleId); @MethodChinaName(cname ="名称") @Caption publicStringgetName(); publicvoidsetName(String name); @MethodChinaName(cname ="角色类型") publicRoleTypegetType(); publicvoidsetType(RoleType type); @MethodChinaName(cname ="级数") publicStringgetRoleNum(); publicvoidsetRoleNum(String num); @MethodChinaName(cname ="系统ID") @Pid publicStringgetSysId(); publicvoidsetSysId(String sysId); @MethodChinaName(cname ="人员") @Ref(ref =RefType.m2m, view =ViewType.grid) publicList<Person>getPersonList(); @MethodChinaName(cname ="部门") @Ref(ref =RefType.m2m, view =ViewType.grid) publicList<Org>getOrgList(); publicList<String>getOrgIdList();}
(3) 实体关系
编辑切换为居中
添加图片注释,不超过 140 字(可选)
仓储建模的一个核心目的是将结构化的数据转变为面向对象的模式,而这其中非常重要的一点则是实体关系的处理,DSM设计中针对数据库表允许用户在导入数据库后再次进行实体关系建模,将数据库表按 1:1 ,1:N, N:N模型建立关系。完成建模后在出码的过程中会根据业务模板设定,进行实体模型的转变,在实体代码中以 @Ref 关系标签完成建模应用。
数据库模型关系 |
实体关系 |
实体注解配置 |
1:N |
一对多 |
@Ref(ref = RefType.o2m) |
N:N |
多对多 |
@Ref(ref = RefType.m2m) |
1:1 |
一对一 |
@Ref(ref = RefType.o2o) |
引用 |
@Ref(ref = RefType.ref) |
|
查找 |
@Ref(ref = RefType.) |
|
实体模型关系在基础的模型上根据仓储模型设计,独立扩展了
publicenumRefTypeimplementsIconEnumstype{ ref("引用","spafont spa-icon-c-databinder"), o2m("一对多","spafont spa-icon-c-treeview"), m2o("多对一","spafont spa-icon-alignwh"), f2f("自循环","spafont spa-icon-cancel"), o2o("一对一","spafont spa-icon-hmirror"), find("查找","xui-icon-search"), m2m("多对多","spafont spa-icon-alignwh"); privatefinalString imageClass; privatefinalString name; RefType(String name,String imageClass){ this.name = name; this.imageClass = imageClass; }}
(4) 仓储建模模板
编辑切换为居中
添加图片注释,不超过 140 字(可选)
编辑切换为居中
添加图片注释,不超过 140 字(可选)
(5)仓储模型常用注解
注解名称 |
用途 |
实例 |
@DBTable |
数据库表映射配置 主要包含了,数据源标识,表名称以及主键信息 |
@DBTable(configKey="fdt",tableName="FDT_LINGDAO",primaryKey="uuid") |
@DBField |
数据库字段配置 |
@DBField(cnName="创建时间",length=0,dbType=ColType.DATETIME,dbFieldName="createtime") |
@Uid |
实体字段,在数据库实体中一般标识为主键,在DDD模型中作为唯一值 |
@Uid |
@Pid |
父级组件字段,通常在关系实体中用于标识父级对象的主键 |
@Pid |
@CustomAnnotation |
常用实体注解,注解属性中会包括,字段的展示类型,可读属性,展示注解等。 |
@CustomAnnotation(caption="职务") |
@Caption |
标题注解一般作用在表格行数据的展示中作为默认显示字段,如Person (人员对象中)会将name作为默认展示选项 |
@Caption |
@Ref |
实体关系属性 |
@Ref(ref = RefType.m2m, view = ViewType.grid) |
@APIEventAnnotation |
API服务注解,是对外服务的标识。添加该注解后,在后续的模型建模中会对应转换为Web API服务 |
@APIEventAnnotation(bindMenu = {CustomMenuItem.search}) |
三,领域建模
(1) 领域建模组成
编辑切换为居中
添加图片注释,不超过 140 字(可选)
(2)领域建模原理
编辑切换为居中
模型渲染原理
OneCode 本身基于JAVA语言体系,是在Java Spring 注解基础上的一套扩展子集,混合编译引擎器通过扩展注解构建完整的Domain模型,通过读取标准Spring 注解完成普通Web数据交付及调度过程。
示例注解说明:
编辑切换为居中
添加图片注释,不超过 140 字(可选)
完整示例代码:
@Controller@RequestMapping("/admin/org/deparment/")@MethodChinaName(cname ="部门管理", imageClass ="bpmfont bpmgongzuoliuzuhuzicaidan")@Aggregation(sourceClass =IDeparmentService.class, rootClass =Org.class)publicinterfaceIDeparmentAPI{ @RequestMapping(method =RequestMethod.POST, value ="Persons") @GridViewAnnotation() @ModuleAnnotation(caption ="人员列表") @APIEventAnnotation(bindMenu ={CustomMenuItem.treeNodeEditor}) @ResponseBody public<KextendsIPersonGrid>ListResultModel<List<K>>getPersons(String orgId); @RequestMapping(method =RequestMethod.POST, value ="loadChild") @APIEventAnnotation(bindMenu ={CustomMenuItem.loadChild}) @ResponseBody public<TextendsIDeparmentTree>ListResultModel<List<T>>loadChild(String parentId); @MethodChinaName(cname ="部门信息") @RequestMapping(method =RequestMethod.POST, value ="DeparmentInfo") @NavGroupViewAnnotation(saveUrl ="admin.org.deparment.saveOrg") @DialogAnnotation @ModuleAnnotation(caption ="编辑部门信息", width ="600", height ="480") @APIEventAnnotation(callback ={CustomCallBack.ReloadParent,CustomCallBack.Close}, bindMenu ={CustomMenuItem.editor}) @ResponseBody public<KextendsIDeparmentNav>ResultModel<K>getDeparmentInfo(String orgId); @MethodChinaName(cname ="添加部门") @RequestMapping(method =RequestMethod.POST, value ="addDeparment") @FormViewAnnotation() @DialogAnnotation @ModuleAnnotation(caption ="添加部门", width ="350", height ="260") @APIEventAnnotation(bindMenu ={CustomMenuItem.add}, autoRun =true) @ResponseBody public<MextendsIAddDeparmentForm>ResultModel<M>addDeparment(String parentId); @MethodChinaName(cname ="保存机构信息") @RequestMapping(value ={"saveOrg"}, method ={RequestMethod.GET,RequestMethod.POST}) @APIEventAnnotation(callback ={CustomCallBack.ReloadParent,CustomCallBack.Close}, bindMenu ={CustomMenuItem.save}) public@ResponseBody ResultModel<Boolean>saveOrg(@RequestBodyIAddDeparmentForm deparmentForm); @MethodChinaName(cname ="删除部门") @RequestMapping(value ={"delOrg"}, method ={RequestMethod.GET,RequestMethod.POST}) @APIEventAnnotation(callback ={CustomCallBack.Reload,CustomCallBack.ReloadParent}, bindMenu ={CustomMenuItem.delete}) public@ResponseBody ResultModel<Boolean>delOrg(String orgId); ;}
(3)聚合配置
编辑切换为居中
建模配置
编辑切换为居中
接口配置
编辑切换为居中
窗体配置
编辑切换为居中
执行事件传递
(4)聚合分类
编辑切换为居中
添加图片注释,不超过 140 字(可选)
(5)聚合根
聚合根设计,通常来标识其独立的域应用,具有全局唯一性的特点。 在 通用域中,具有时间轴维度的对象描述,如工作流中的流程示例(ProcessInst)对象。在获取聚合根后,可以依据时间轴一次向前获取,流程定义对象,向后获取可以取得流程历史数据,而根据当前节点则可以获取权限,数据表单、业务示例状态的等等实体数据。
编辑切换为居中
流程示例聚合根配置
流程实例聚合根源码
@Entity@MethodChinaName(cname ="流程实例")@Aggregation(type =AggregationType.aggregationRoot, sourceClass =ProcessInst.class, rootClass =ProcessInst.class)publicinterfaceProcessInstextends java.io.Serializable{ @MethodChinaName(cname ="流程实例UUID") @Uid publicStringgetProcessInstId(); @MethodChinaName(cname ="流程定义UUID") @Pid publicStringgetProcessDefId(); @MethodChinaName(cname ="流程定义版本UUID") @Pid publicStringgetProcessDefVersionId(); @MethodChinaName(cname ="流程实例名称") publicStringgetName(); @MethodChinaName(cname ="紧急程度") publicStringgetUrgency(); @MethodChinaName(cname ="流程实例状态") publicProcessInstStatusgetState(); @MethodChinaName(cname ="流程实例副本数量") publicintgetCopyNumber(); @MethodChinaName(cname ="程实例启动时间") publicDategetStartTime(); @MethodChinaName(cname ="流程实例办结时间") publicDategetEndTime(); @MethodChinaName(cname =" 流程实例时间限制") publicDategetLimitTime(); @MethodChinaName(cname ="流程实例状态") publicProcessInstStatusgetRunStatus(); @MethodChinaName(cname ="流程定义版本") @Ref(ref =RefType.m2o, view =ViewType.grid) publicProcessDefVersiongetProcessDefVersion()throwsBPMException; @MethodChinaName(cname ="流程定义") @Ref(ref =RefType.m2o, view =ViewType.dic) publicProcessDefgetProcessDef()throwsBPMException; @MethodChinaName(cname ="活动实例") @Ref(ref =RefType.o2m, view =ViewType.grid) publicList<ActivityInst>getActivityInstList()throwsBPMException; @MethodChinaName(cname ="流程属性值", returnStr ="getWorkflowAttribute($R('attName'))", display =false) publicObjectgetWorkflowAttribute(ProcessInstAtt name); @MethodChinaName(cname ="权限属性值", returnStr ="getRightAttribute($R('attName'))", display =false) publicObjectgetRightAttribute(ProcessInstAtt name); @MethodChinaName(cname ="应用属性值", returnStr ="getAppAttribute($R('attName'))", display =false) publicObjectgetAppAttribute(ProcessInstAtt name); @MethodChinaName(cname ="定制属性值", returnStr ="getAttribute($R('attName'))", display =false) publicStringgetAttribute(String name); @MethodChinaName(cname ="取得流程中的所有属性值", returnStr ="getAllAttribute()", display =false) @Ref(ref =RefType.o2m, view =ViewType.grid) publicList<AttributeInst>getAllAttribute(); @MethodChinaName(cname ="个人定制属性值", returnStr ="getAttribute($R('personId'),$R('attName'))", display =true) publicStringgetPersonAttribute(String personId,String name); @MethodChinaName(cname ="设置定制属性", returnStr ="setAttribute($R('attName'),$R('value'))", display =false) publicvoidsetAttribute(String name,String value)throwsBPMException; @MethodChinaName(cname ="设置个人定制属性", returnStr ="setAttribute($R('personId'),$R('attName'),$R('value'))", display =false) publicvoidsetPersonAttribute(String personId,String name,String value)throwsBPMException; @MethodChinaName(cname ="更新流程实例名称(公文标题)", returnStr ="updateProcessInstUrgency($R('processInstName'))") publicReturnTypeupdateProcessInstName(String name) throwsBPMException; @MethodChinaName(cname ="更新流程实例紧急程度", returnStr ="updateProcessInstUrgency($R('urgency'))") publicReturnTypeupdateProcessInstUrgency( String urgency)throwsBPMException; @MethodChinaName(cname ="流程实例挂起", returnStr ="suspendProcessInst()", display =false) publicReturnTypesuspendProcessInst() throwsBPMException; @MethodChinaName(cname ="继续流程实例", returnStr ="resumeProcessInst()", display =false) publicReturnTyperesumeProcessInst() throwsBPMException; @MethodChinaName(cname ="取得活动的历史数据, 根据流程实例") publicList<ActivityInstHistory>getActivityInstHistoryListByProcessInst()throwsBPMException; @MethodChinaName(cname ="中止流程实例", returnStr ="abortProcessInst()", display =false) publicReturnTypeabortProcessInst() throwsBPMException; @MethodChinaName(cname ="流程实例完成", returnStr ="completeProcessInst()", display =false) publicReturnTypecompleteProcessInst() throwsBPMException; @MethodChinaName(cname ="删除流程实例", returnStr ="deleteProcessInst()", display =false) publicReturnTypedeleteProcessInst() throwsBPMException; @MethodChinaName(cname ="获取表单数据") publicDataMapgetFormValues()throwsBPMException; @MethodChinaName(cname ="更新表单数据") publicvoidupdateFormValues(DataMap dataMap)throwsBPMException;}
(6)聚合实体
聚合实体,通常用来描述独立实体机构,例如业务表单中单表或简单关联表关系。通常只包含简单的值关系,功能上也仅限于,查询列表、保存表单等简单应用。
编辑切换为居中
单表表单
代码示例
@Controller@RequestMapping("/test/fdtlingdaoservice/")@Aggregation(type=AggregationType.aggregationEntity,sourceClass=FdtLingdaoService.class)publicinterfaceFdtLingdaoAPI { @APIEventAnnotation(bindMenu=CustomMenuItem.search) @RequestMapping(value="searchUrl") @ModuleAnnotation @GridViewAnnotation @ResponseBody public ListResultModel<List<FindGridView>> find (FdtLingdao fdtLingdao); @APIEventAnnotation(bindMenu={CustomMenuItem.add,CustomMenuItem.editor}) @RequestMapping(value="addPath") @ModuleAnnotation @FormViewAnnotation @ResponseBody public ResultModel<GetFdtLingdaoInfoView> getFdtLingdaoInfo (String uuid); @APIEventAnnotation(bindMenu=CustomMenuItem.save,callback={CustomCallBack.ReloadParent,CustomCallBack.Close}) @RequestMapping(value="update") @ResponseBody public ResultModel<FdtLingdao> update (@RequestBodyFdtLingdao fdtLingdao); @RequestMapping(value="findByWhere") @ResponseBody public ListResultModel<List<FdtLingdao>> findByWhere (String where); @APIEventAnnotation(bindMenu=CustomMenuItem.delete,callback=CustomCallBack.Reload) @RequestMapping(value="delete") @ResponseBody public ResultModel<Boolean> delete (String uuid); @APIEventAnnotation(bindMenu=CustomMenuItem.reload) @RequestMapping(value="dataUrl") @ModuleAnnotation @GridViewAnnotation @ResponseBody public ListResultModel<List<FindAllGridView>> findAll (); }
(6)动作菜单
动作菜单在DDD模型中并未定义,但在低代码应用却有着很重要的一席。
动作菜单建模中,主要将菜单展现与关联动作结合在一起。
编辑切换为居中
工作流发送菜单建模
菜单展现位置
编辑切换为居中
添加图片注释,不超过 140 字(可选)
编辑切换为居中
编辑器右键菜单
常用菜单注解
注解 |
位置 |
示例 |
@ToolBarMenu |
容器顶部工具栏 |
@ToolBarMenu(hAlign = HAlignType.left, handler = false, menuClass = JavaRepositoryEditorTools.class) |
@MenuBarMenu |
顶部菜单栏 |
@MenuBarMenu(menuType = CustomMenuType.sub, caption = "新建", imageClass = "xuicon xui-uicmd-add", index = 5) |
@BottomBarMenu |
容器底部按钮栏 |
@BottomBarMenu(menuClass = CustomBuildAction.class) |
@PageBar |
分页栏 |
@PageBar(pageCount = 100) |
@GridRowCmd |
列表行操作按钮栏 |
@GridRowCmd(tagCmdsAlign = TagCmdsAlign.left, menuClass = {AttachMentService.class}) |
@RightContextMenu |
右键菜单栏 |
@RightContextMenu(menuClass = JavaViewPackageMenu.class) |
@Controller@RequestMapping(value ={"/java/agg/context/"})@MenuBarMenu(menuType =CustomMenuType.component, caption ="菜单")@Aggregation(type =AggregationType.menu)publicclassJavaAggPackageMenu{ @RequestMapping(method =RequestMethod.POST, value ="paste") @CustomAnnotation(imageClass ="spafont spa-icon-paste", index =1, caption ="粘贴") @APIEventAnnotation(customRequestData ={RequestPathEnum.treeview,RequestPathEnum.sTagVar}, callback =CustomCallBack.TreeReloadNode) public@ResponseBody TreeListResultModel<List<JavaAggTree>>paste(String sfilePath,String packageName,String domainId,String projectName){ TreeListResultModel<List<JavaAggTree>> result =newTreeListResultModel<List<JavaAggTree>>(); try{ DSMFactory dsmFactory =DSMFactory.getInstance(); File desFile =newFile(sfilePath); DomainInst domainInst = dsmFactory.getAggregationManager().getDomainInstById(domainId); JavaSrcBean srcBean = dsmFactory.getTempManager().genJavaSrc(desFile, domainInst,null); DSMFactory.getInstance().getBuildFactory().copy(srcBean, packageName); result.setIds(Arrays.asList(newString[]{domainId +"|"+ packageName})); }catch(Exception e){ e.printStackTrace(); } return result; } @RequestMapping(method =RequestMethod.POST, value ="reLoad") @CustomAnnotation(imageClass ="xuicon xui-refresh", index =1, caption ="刷新") @APIEventAnnotation(customRequestData =RequestPathEnum.treeview, callback =CustomCallBack.TreeReloadNode) public@ResponseBody TreeListResultModel<List<JavaAggTree>>reLoad(String packageName,String domainId,String filePath){ TreeListResultModel<List<JavaAggTree>> result =newTreeListResultModel<List<JavaAggTree>>(); String id = domainId +"|"+ packageName; result.setIds(Arrays.asList(newString[]{id})); return result; } @RequestMapping(value ={"split"}) @Split @CustomAnnotation(index =2) @ResponseBody publicResultModel<Boolean>split2(){ ResultModel<Boolean> result =newResultModel<Boolean>(); return result; } @RequestMapping(value ="UploadFile") @APIEventAnnotation(autoRun =true) @DialogAnnotation(width ="450", height ="380", caption ="上传JAVA文件") @ModuleAnnotation @FormViewAnnotation @CustomAnnotation(caption ="上传", index =3, imageClass ="xui-icon-upload", tips ="上传") public@ResponseBody ResultModel<UPLoadFile>uploadFile(String domainId,String packageName){ ResultModel<UPLoadFile> resultModel =newResultModel<UPLoadFile>(); try{ UPLoadFile upLoadFile =newUPLoadFile(domainId, packageName); resultModel.setData(upLoadFile); }catch(Exception e){ e.printStackTrace(); } return resultModel; } @RequestMapping(value ={"split"}) @Split @CustomAnnotation(index =4) @ResponseBody publicResultModel<Boolean>split6(){ ResultModel<Boolean> result =newResultModel<Boolean>(); return result; } @RequestMapping(method =RequestMethod.POST, value ="newApp") @CustomAnnotation(imageClass ="xuicon xui-uicmd-add", index =5) @MenuBarMenu(menuType =CustomMenuType.sub, caption ="新建", imageClass ="xuicon xui-uicmd-add", index =5) publicJavaAggNewMenugetJavaJarAction(){ returnnewJavaAggNewMenu(); } @RequestMapping(method =RequestMethod.POST, value ="importAgg") @CustomAnnotation(imageClass ="xuicon xui-uicmd-add", index =6) @MenuBarMenu(menuType =CustomMenuType.sub, caption ="导入", imageClass ="spafont spa-icon-html", index =5) publicJavaAggImportMenuimportAgg(){ returnnewJavaAggImportMenu(); } @RequestMapping(value ={"split"}) @Split @CustomAnnotation(index =7) @ResponseBody publicResultModel<Boolean>split7(){ ResultModel<Boolean> result =newResultModel<Boolean>(); return result; } @MethodChinaName(cname ="删除") @RequestMapping(method =RequestMethod.POST, value ="delete") @CustomAnnotation(imageClass ="xuicon xui-icon-minus", index =8) @APIEventAnnotation(customRequestData =RequestPathEnum.treeview, callback =CustomCallBack.TreeReloadNode) public@ResponseBody TreeListResultModel<List<JavaAggTree>>delete(String domainId,String parentId,String filePath,String javaTempId){ TreeListResultModel<List<JavaAggTree>> result =newTreeListResultModel<List<JavaAggTree>>(); try{ File desFile =newFile(filePath); DSMFactory dsmFactory =DSMFactory.getInstance(); DomainInst domainInst = dsmFactory.getAggregationManager().getDomainInstById(domainId); if(desFile.exists()){ if(desFile.isDirectory()){ JavaPackage javaPackage = domainInst.getPackageByFile(desFile); dsmFactory.getTempManager().deleteJavaPackage(javaPackage); }else{ JavaSrcBean srcBean = dsmFactory.getTempManager().genJavaSrc(desFile, domainInst, javaTempId); dsmFactory.getTempManager().deleteJavaFile(srcBean); } } result.setIds(Arrays.asList(newString[]{parentId})); }catch(JDSException e){ e.printStackTrace(); } return result; } publicESDChromegetCurrChromeDriver(){ Object handleId =JDSActionContext.getActionContext().getParams("handleId"); ChromeDriver chrome =null; if(handleId !=null){ chrome =ESDEditor.getInstance().getChromeDriverById(handleId.toString()); } if(chrome ==null){ chrome =ESDEditor.getInstance().getCurrChromeDriver(); } returnnewESDChrome(chrome); }}
(7)通用域
通用域将系统中常用服务进行了独立分类可以在工程构建时导入进来。
编辑切换为居中
通用域管理
(8)API服务接口
api服务接口是手工代码接入的域服务,在普通java类上加上聚和接口后会统一归类到该类型管理。
(9)领域模型常用注解
注解名称 |
用途 |
实例 |
@RequestMapping |
直接使用的SpringMvc注解用于将当前方法标识为,web可访问 |
@RequestMapping(value = {"AggAPITree"}, method = {RequestMethod.GET, RequestMethod.POST}) |
@ModuleAnnotation |
视图标识,在方法上标识改注解后会被模型编译器识别为视图模型将其内部对象渲染为视图。 |
@ModuleAnnotation(dynLoad = true, imageClass = "spafont spa-icon-moveforward", caption = "模块授权") |
@ResponseBody |
直接使用的SpringMvc注解,标识为JSON数据返回 |
@ResponseBody |
@DialogAnnotation |
添加该标识时,当前端路由到当前方法时,以独立窗口的方式返回 |
@DialogAnnotation(width = "850", height = "750") |
@Aggregation |
领域标识,在类注解中添加该标识,会被DSM引擎自动索引并根据注解中指定类型加载到相关的实体列表中 |
@Aggregation(type = AggregationType.customDomain, sourceClass = PersonService.class, rootClass = Person.class) |
@*Domain |
通用域标识 |
@OrgDomain @BpmDomain @VfsDomain @MsgDomain @NavDomain |
@*TreeView |
树形注解包括了,导航树、弹出字典树,折叠分组树等注解集合 |
@TreeViewAnnotation @NavTreeViewAnnotation @NavFoldingTreeViewAnnotation @PopTreeViewAnnotation |
@GridViewAnnotation |
数据列表注解 |
|
@GalleryView*Annotation |
详情图形混合注解 |
@GalleryViewAnnotation @NavGalleryViewAnnotation |
@*TabsViewAnnotation |
Tab切换页 |
@TabsViewAnnotation @NavTabsViewAnnotation @NavFoldingTabsViewAnnotation |
@PopMenuViewAnnotation |
菜单导航 |
@PopMenuViewAnnotation |
@NavGroupViewAnnotation |
分组表单 |
@NavGroupViewAnnotation |
@FormViewAnnotation |
表单注解 |
@FormViewAnnotation |
@*ButtonViewsViewAnnotation |
按钮栏视图 |
@ButtonViewsAnnotation @NavButtonViewsAnnotation |
后续章节内容介绍
在下一章节中,我们将重点介绍,OneCode视图工厂以及,模块组装,权限设定、菜单应用等相关工具使用。
章节预览:
视图工厂,最终面向用户的展现方式,在建模中通常会有相关的服务通过聚合实体与关系完成初步的视图构建。
编辑切换为居中
视图工厂组成
在领域工厂中,更多是将贫血性的基础实体对象进行聚合分类整理,形成更利于业务理解与操作的充血模型,并且通过在其接口模型上扩展注解的方式实现其低耦合应用。视图工厂中仍然延续这一风格设计将普通单一的组件通过,后端JAVA代码的聚合将常用功能以及辅助组件进行业务封装形成独立的视图组件。
常用列表功能
编辑切换为居中
常用配置
列表信息配置
编辑切换为居中
添加图片注释,不超过 140 字(可选)