ABP 框架代码批量生成器
需要最新源码,或技术提问,请加qq群:538327407,由于源码在不断完善,会在之后同步到开源项目中
简介
用abp 框架快两年了,用它完成了多个项目,作为cto同时也作为架构师,在应对中小型项目时候,我们通常选择abp(内部大型的物联网架构采用自己的框架),感觉这款框架真心不错。虽然开源社区有也有很多写了几套代码生成器,但是我用完之后,总是感觉不能达到我自己想要的效果,我个人还是比较喜欢一步到位,批量生成,所以就写了这套基于codesmith的代码生成器,这一套在项目中还算稳定。
模板介绍
先看一下代码结构
我们的项目中我规划使用的是spa的,所以一般会生成常规 四个目录,分别是如下
其余的中英文,还有权限、以及dbcontext 部分相对数量比较少,统一改造,生成单个文件进行copy。
最后使用templatebuid 自动生成上面的批量文件。
代码解析和使用
每个代码生成器部分需要先配置对应的项目名称,和model等,细节需要自己去了解
常规简单操作
一般需要我们用powerdesign等设计工具,设计好对应的表,标注要注释,先临时生成一个数据库,通过codesmith 生成代码后,在通过code first 形式,真正在abp 对应的数据库中生成数据库表。
以下文件是templatebuid.cst 文件,配置完成后,
生成代码操作,先编译,后生成。
详细代码举例说明
由于篇幅有限,我就简单说明一下repository、appauthorizationprovider、view中的createoreditmodal 进行简单说明
1、repository
常规封装增删改查等操作,我在项目中重写了基类方法,封装了批量等操作,但没有和代码生成器组合起来,常规的业务里面不需要批量操作
其中 默认主键都是位id,如果实际项目中有需求,主键要为其他字段,需要手动修改。目前我封装的主要针对id 是int 类型、guid 类型做了不同代码输出
1 <%@ codetemplate language="c#" targetlanguage="c#" responseencoding="utf-8" description="generates a single entity business class." debug="true" %> 2 <%@ property name="sourcetable" type="schemaexplorer.tableschema" category="2.数据库" description="database table that this entity should be based on." %> 3 <%@ property name="tableprefixes" type="string" default="" optional="true" category="2.数据库" description="the table prefix to be cut from the class name" %> 4 <%@ property name="rootnamespace" type="string" default="hashblockchain" optional="false" category="1.名称空间" description="系统名称空间的根名称." %> 5 <%@ property name="namespace" type="string" default="zldb_domain" optional="false" category="1.名称空间" description="系统当前所属文件夹的名称(命名空间相关)." %> 6 <%@ property name="foldernamespace" type="string" default="" optional="true" category="1.名称空间" description="系统名称空间的model名称." %> 7 <%@ property name="prefixlength" type="int32" default="0" optional="false" category="2.数据库" description="数据表前缀截取长度." %> 8 <%@ assembly name="schemaexplorer" %> 9 <%@ assembly name="codesmith.basetemplates" %> 10 <%@ assembly name="system.data" %> 11 <%@ import namespace="schemaexplorer" %> 12 <%@ import namespace="system.data" %> 13 <%string tableclass=getclassname(sourcetable, "", 0); %> 14 <% foldernamespace=sourcetable.name.tostring();%> 15 <%string tablename=sourcetable.name.tostring(); %> 16 <%string paramname=getparamname(tablename); %> 17 18 using abp.application.services; 19 using abp.application.services.dto; 20 using abp.automapper; 21 using abp.domain.repositories; 22 using abp.domain.uow; 23 using automapper; 24 using system; 25 using system.collections.generic; 26 using system.data.entity; 27 using system.linq; 28 using system.linq.expressions; 29 using system.text; 30 using system.threading.tasks; 31 using system.linq.dynamic; 32 using abp.linq.extensions; 33 using <%= rootnamespace %>.<%=namespace%>.dtos; 34 using <%= rootnamespace %>.dto; 35 using <%= rootnamespace %>.authorization.<%=tablename%>.exporting; 36 namespace <%= rootnamespace %>.<%=namespace%> 37 { 38 39 <% foreach (columnschema column in sourcetable.columns) { %> 40 <% if (column.isprimarykeymember) { %> 41 42 <%string temptype = getcsharpvariabletype(column); %> 43 44 <% if (temptype=="guid") { %> 45 /// <summary> 46 /// <%=sourcetable.description%> 业务实现接口 47 /// </summary> 48 public class <%=tablename%>appservice : abpzerotemplateappservicebase, i<%=tablename%>appservice 49 { 50 private readonly irepository<<%=tablename%>, guid> _<%=paramname%>repository; 51 private readonly i<%=tablename%>listexcelexporter _i<%=tablename%>listexcelexporter; 52 53 /// <summary> 54 /// 构造函数自动注入我们所需要的类或接口 55 /// </summary> 56 public <%=tablename%>appservice(irepository<<%=tablename%>, guid> <%=paramname%>repository,i<%=tablename%>listexcelexporter i<%=tablename%>listexcelexporter) 57 { 58 _<%=paramname%>repository = <%=paramname%>repository; 59 _i<%=tablename%>listexcelexporter = i<%=tablename%>listexcelexporter; 60 61 } 62 63 /// <summary> 64 /// 获取所有数据列表 65 /// </summary> 66 /// <returns>返回数据集合</returns> 67 public async task<list<<%=tablename%>dto>> getalllist() 68 { 69 //调用task仓储的特定方法getallwithpeople 70 var resultlist = await _<%=paramname%>repository.getalllistasync(); 71 return mapper.map<list<<%=tablename%>dto>>(resultlist).tolist(); 72 } 73 74 /// <summary> 75 /// 获取分页数据列表 分页具体代码需要适当修改,如orderby 需要匹配 创建时间 或者其他数据id(int) 76 /// </summary> 77 /// <returns>返回数据集合</returns> 78 public async task<pagedresultdto<<%=tablename%>dto>> getpagedlistasync(pagedandfilteredinputdto input) 79 { 80 var query = _<%=paramname%>repository.getall(); 81 //todo:根据传入的参数添加过滤条件 82 83 var resultcount = await query.countasync(); 84 var result<%=paramname%> = await query 85 .orderby(x=>x.id) 86 .pageby(input) 87 .tolistasync(); 88 89 var resultlistdtos = result<%=paramname%>.mapto<list<<%=tablename%>dto>>(); 90 91 if (!string.isnullorempty(input.sorting)) { 92 resultlistdtos = resultlistdtos.orderby(input.sorting).tolist(); 93 } 94 95 return new pagedresultdto<<%=tablename%>dto>( 96 resultcount, 97 resultlistdtos 98 ); 99 } 100 101 /// <summary> 102 /// 获取指定条件的数据列表 webapi 无法使用 103 /// </summary> 104 /// <returns>返回数据集合</returns> 105 public async task<list<<%=tablename%>dto>> getlistbycodition(expression<func<<%=tablename%>, bool>> predicate) 106 { 107 108 var resultlist = await _<%=paramname%>repository.getalllistasync(predicate); 109 return mapper.map<list<<%=tablename%>dto>>(resultlist).tolist(); 110 } 111 112 113 /// <summary> 114 /// 导出excel 具体方法 115 /// </summary> 116 /// <returns>excel文件</returns> 117 /// public async task<filedto> get<%=tablename%>toexcel() 118 ///{ 119 /// var resultlist = await _<%=paramname%>repository.getalllistasync(); 120 /// var <%=paramname%>dtos= mapper.map<list<<%=tablename%>dto>>(resultlist).tolist(); 121 /// return _i<%=tablename%>listexcelexporter.exporttofile(<%=paramname%>dtos); 122 /// } 123 124 /// <summary> 125 /// 根据指定id 获取数据实体 126 /// </summary> 127 /// <param name="input">当前id</param> 128 /// <returns></returns> 129 public async task<<%=tablename%>dto> get<%=tablename%>foreditasync(nullableiddto<system.guid> input) 130 { 131 var output = new <%=tablename%>dto(); 132 133 <%=tablename%>dto <%=paramname%>editdto; 134 135 if (input.id.hasvalue) 136 { 137 var entity = await _<%=paramname%>repository.getasync(input.id.value); 138 <%=paramname%>editdto = entity.mapto<<%=tablename%>dto>(); 139 } 140 else 141 { 142 <%=paramname%>editdto = new <%=tablename%>dto(); 143 } 144 145 output = <%=paramname%>editdto; 146 return output; 147 } 148 149 /// <summary> 150 /// 根据id创建或编辑操作 151 /// </summary> 152 /// <param name="input">实体</param> 153 /// <returns></returns> 154 public async task createorupdate<%=tablename%>async(<%=tablename%>dto input) 155 { 156 if (!string.isnullorwhitespace(input.id)) 157 { 158 await update(input); 159 } 160 else 161 { 162 await create(input); 163 } 164 } 165 166 /// <summary> 167 /// 新增 168 /// </summary> 169 /// <param name="input">新增参数</param> 170 /// <returns>新增实体</returns> 171 public async task<guid> create(<%=tablename%>dto input) 172 { 173 input.id = new <%=tablename%>().id.tostring(); 174 var resultobj = input.mapto<<%=tablename%>>(); 175 var result = await _<%=paramname%>repository.insertasync(resultobj); 176 177 return result.id; 178 } 179 180 /// <summary> 181 /// 修改 182 /// </summary> 183 /// <param name="input">修改参数</param> 184 /// <returns>修改实体</returns> 185 public async task<<%=tablename%>dto> update(<%=tablename%>dto input) 186 { 187 <%=tablename%> obj = await _<%=paramname%>repository.getasync(new guid(input.id)); 188 input.mapto(obj); 189 var result = await _<%=paramname%>repository.updateasync(obj); 190 return obj.mapto<<%=tablename%>dto>(); 191 } 192 193 /// <summary> 194 /// 删除 195 /// </summary> 196 /// <param name="input">删除dto</param> 197 /// <returns>无返回值</returns> 198 public async system.threading.tasks.task delete(entitydto<string> input) 199 { 200 await _<%=paramname%>repository.deleteasync(new guid(input.id)); 201 } 202 203 /// <summary> 204 /// 删除 webapi 无法使用 205 /// </summary> 206 /// <param name="predicate">删除条件</param> 207 /// <returns>无返回值</returns> 208 public async system.threading.tasks.task deletebycondition(expression<func<<%=tablename%>, bool>> predicate) 209 { 210 await _<%=paramname%>repository.deleteasync(predicate); 211 212 } 213 } 214 215 216 <% } else {%> 217 /// <summary> 218 /// <%=sourcetable.description%> 业务实现接口 219 /// </summary> 220 public class <%=tablename%>appservice : abpzerotemplateappservicebase, i<%=tablename%>appservice 221 { 222 private readonly irepository<<%=tablename%>, <%=temptype%>> _<%=paramname%>repository; 223 private readonly i<%=tablename%>listexcelexporter _i<%=tablename%>listexcelexporter; 224 225 /// <summary> 226 /// 构造函数自动注入我们所需要的类或接口 227 /// </summary> 228 public <%=tablename%>appservice(irepository<<%=tablename%>, <%=temptype%>> <%=paramname%>repository,i<%=tablename%>listexcelexporter i<%=tablename%>listexcelexporter) 229 { 230 _<%=paramname%>repository = <%=paramname%>repository; 231 _i<%=tablename%>listexcelexporter = i<%=tablename%>listexcelexporter; 232 233 } 234 235 /// <summary> 236 /// 获取所有数据列表 237 /// </summary> 238 /// <returns>返回数据集合</returns> 239 public async task<list<<%=tablename%>dto>> getalllist() 240 { 241 //调用task仓储的特定方法getallwithpeople 242 var resultlist = await _<%=paramname%>repository.getalllistasync(); 243 return mapper.map<list<<%=tablename%>dto>>(resultlist).tolist(); 244 } 245 246 /// <summary> 247 /// 获取分页数据列表 分页具体代码需要适当修改,如orderby 需要匹配 创建时间 或者其他数据id(int) 248 /// </summary> 249 /// <returns>返回数据集合</returns> 250 public async task<pagedresultdto<<%=tablename%>dto>> getpagedlistasync(pagedandfilteredinputdto input) 251 { 252 var query = _<%=paramname%>repository.getall(); 253 //todo:根据传入的参数添加过滤条件 254 255 var resultcount = await query.countasync(); 256 var result<%=paramname%> = await query 257 .orderby(x=>x.id) 258 .pageby(input) 259 .tolistasync(); 260 261 var resultlistdtos = result<%=paramname%>.mapto<list<<%=tablename%>dto>>(); 262 return new pagedresultdto<<%=tablename%>dto>( 263 resultcount, 264 resultlistdtos 265 ); 266 } 267 268 /// <summary> 269 /// 获取指定条件的数据列表 webapi 无法使用 270 /// </summary> 271 /// <returns>返回数据集合</returns> 272 public async task<list<<%=tablename%>dto>> getlistbycodition(expression<func<<%=tablename%>, bool>> predicate) 273 { 274 275 var resultlist = await _<%=paramname%>repository.getalllistasync(predicate); 276 return mapper.map<list<<%=tablename%>dto>>(resultlist).tolist(); 277 } 278 279 280 /// <summary> 281 /// 导出excel 具体方法 282 /// </summary> 283 /// <returns>excel文件</returns> 284 /// public async task<filedto> get<%=tablename%>toexcel() 285 ///{ 286 /// var resultlist = await _<%=paramname%>repository.getalllistasync(); 287 /// var <%=paramname%>dtos= mapper.map<list<<%=tablename%>dto>>(resultlist).tolist(); 288 /// return _i<%=tablename%>listexcelexporter.exporttofile(<%=paramname%>dtos); 289 /// } 290 291 /// <summary> 292 /// 根据指定id 获取数据实体 293 /// </summary> 294 /// <param name="input">当前id</param> 295 /// <returns></returns> 296 public async task<<%=tablename%>dto> get<%=tablename%>foreditasync(nullableiddto<<%=temptype%>> input) 297 { 298 var output = new <%=tablename%>dto(); 299 300 <%=tablename%>dto <%=paramname%>editdto; 301 302 if (convert.toint32(input.id)>0) 303 { 304 var entity = await _<%=paramname%>repository.getasync(convert.toint32(input.id)); 305 <%=paramname%>editdto = entity.mapto<<%=tablename%>dto>(); 306 } 307 else 308 { 309 <%=paramname%>editdto = new <%=tablename%>dto(); 310 } 311 312 output = <%=paramname%>editdto; 313 return output; 314 } 315 316 /// <summary> 317 /// 根据id创建或编辑操作 318 /// </summary> 319 /// <param name="input">实体</param> 320 /// <returns></returns> 321 public async task createorupdate<%=tablename%>async(<%=tablename%>dto input) 322 { 323 if (convert.toint32(input.id)>0) 324 { 325 await update(input); 326 } 327 else 328 { 329 await create(input); 330 } 331 } 332 333 /// <summary> 334 /// 新增 335 /// </summary> 336 /// <param name="input">新增参数</param> 337 /// <returns>新增实体</returns> 338 public async task<<%=temptype%>> create(<%=tablename%>dto input) 339 { 340 input.id = new <%=tablename%>().id.tostring(); 341 var resultobj = input.mapto<<%=tablename%>>(); 342 var result = await _<%=paramname%>repository.insertasync(resultobj); 343 344 return result.id; 345 } 346 347 /// <summary> 348 /// 修改 349 /// </summary> 350 /// <param name="input">修改参数</param> 351 /// <returns>修改实体</returns> 352 public async task<<%=tablename%>dto> update(<%=tablename%>dto input) 353 { 354 <%=tablename%> obj = await _<%=paramname%>repository.getasync(convert.toint32(input.id)); 355 input.mapto(obj); 356 var result = await _<%=paramname%>repository.updateasync(obj); 357 return obj.mapto<<%=tablename%>dto>(); 358 } 359 360 /// <summary> 361 /// 删除 362 /// </summary> 363 /// <param name="input">删除dto</param> 364 /// <returns>无返回值</returns> 365 public async system.threading.tasks.task delete(entitydto<string> input) 366 { 367 await _<%=paramname%>repository.deleteasync(convert.toint32(input.id)); 368 } 369 370 /// <summary> 371 /// 删除 webapi 无法使用 372 /// </summary> 373 /// <param name="predicate">删除条件</param> 374 /// <returns>无返回值</returns> 375 public async system.threading.tasks.task deletebycondition(expression<func<<%=tablename%>, bool>> predicate) 376 { 377 await _<%=paramname%>repository.deleteasync(predicate); 378 379 } 380 } 381 382 383 <% }%> 384 <% }%> <% }%> 385 386 387 } 388 389 390 391 392 <script runat="template"> 393 <!-- #include file="templateutilities.cs" --> 394 </script>
2、appauthorizationprovider.cst 是要和apppermissions.cst 一起使用的,我在实际项目中拆分了原有abp代码,实现了自己的整合的版本,尽量减少对abp 原有代码的耦合
abpzerotemplateapplicationmodule 中的configuration.authorization.providers.add<customsappauthorizationprovider>(); 确保注入
<%-- name: author: description: --%> <%@ template language="c#" targetlanguage="text" src="" inherits=""debug="false" compilerversion="v4.0" %> <%@ assembly name="schemaexplorer" %> <%@ import namespace="schemaexplorer" %> <%@ property name="sourcedatabase" deepload="true" type="schemaexplorer.databaseschema" %> <%@ property name="tables" type="tableschemacollection" optional="true" category="2.数据库" description="tables to inclue" %> <%@ template language="c#" targetlanguage="text" %> <%@ property name="samplestringproperty" default="somevalue" type="system.string" %> <%@ property name="samplebooleanproperty" default="true" type="system.boolean" %> <%@ property name="rootnamespace" type="string" default="hashblockchain" optional="false" category="1.名称空间" description="系统名称空间的根名称." %> <%@ property name="namespace" type="string" default="zldb_domain" optional="false" category="1.名称空间" description="系统当前所属文件夹的名称(命名空间相关)." %> my static content here. my dynamic content here: "<%= samplestringproperty %>" call a script method: <%= samplemethod() %> <% if (samplebooleanproperty) { %> my conditional content here. <% } %> <script runat="template"> // my methods here. public string samplemethod() { return "method output."; } </script> using system.linq; using abp.authorization; using abp.localization; using <%=rootnamespace%>.authorization; //-------------------------------------------------------------------------------------------------------------------------------------------------------------- //简介:abp 权限配置,生成后要在 abpzerotemplateapplicationmodule 中的configuration.authorization.providers.add<customsappauthorizationprovider>(); 确保注入 // // // // //作者: //-------------------------------------------------------------------------------------------------------------------------------------------------------------- namespace <%= rootnamespace %>.<%=namespace%>.authorization { /// <summary> /// 权限配置都在这里。 /// 给权限默认设置服务 /// see <see cref="customsapppermissions"/> for all permission names. /// </summary> public class customsappauthorizationprovider : authorizationprovider { public override void setpermissions(ipermissiondefinitioncontext context) { //在这里配置了自定义 的权限。 var pages = context.getpermissionornull(apppermissions.pages) ?? context.createpermission(apppermissions.pages, l("pages")); var entitynamemodel = pages.children.firstordefault(p => p.name == apppermissions.pages_administration) ?? pages.createchildpermission(apppermissions.pages_administration, l("administration")); <% foreach(tableschema t in tables){ %> <%string tablename=t.name.tostring(); %> <%string paramname=getparamname(tablename); %> //<%=t.description%> 权限 var <%=paramname%> = entitynamemodel.createchildpermission(customsapppermissions.<%=t.name %>, l("<%=t.name %>")); <%=paramname%>.createchildpermission(customsapppermissions.<%=t.name %>_create<%=t.name %>, l("create<%=t.name %>")); <%=paramname%>.createchildpermission(customsapppermissions.<%=t.name %>_edit<%=t.name %>, l("edit<%=t.name %>")); <%=paramname%>.createchildpermission(customsapppermissions.<%=t.name %>_delete<%=t.name %>, l("delete<%=t.name %>")); <% }%> } private static ilocalizablestring l(string name) { return new localizablestring(name, abpzerotemplateconsts.localizationsourcename); } } } <script runat="template"> <!-- #include file="templateutilities.cs" --> </script>
3、view 文件夹中的createoreditmodal.cst
这个是view 视图中基于angular.js,我在这上面封装数据验证,如果不需要的可以自己手动调整,并且 主动拆分为单列和两列的模板,需要自动手动改动
<%@ codetemplate language="c#" targetlanguage="c#" responseencoding="utf-8" description="generates a single entity business class." debug="true" %> <%@ property name="sourcetable" type="schemaexplorer.tableschema" category="2.数据库" description="database table that this entity should be based on." %> <%@ property name="tableprefixes" type="string" default="" optional="true" category="2.数据库" description="the table prefix to be cut from the class name" %> <%@ property name="rootnamespace" type="string" default="managementsystem" optional="false" category="1.名称空间" description="系统名称空间的根名称." %> <%@ property name="title" type="string" default="createoreditmodal" optional="false" category="1.名称空间" description="系统名称空间的model名称." %> <%@ property name="prefixlength" type="int32" default="0" optional="false" category="2.数据库" description="数据表前缀截取长度." %> <%@ assembly name="schemaexplorer" %> <%@ assembly name="codesmith.basetemplates" %> <%@ assembly name="system.data" %> <%@ import namespace="schemaexplorer" %> <%@ import namespace="system.data" %> <%string tableclass=getclassname(sourcetable, "", 0); %> <%string tablename=sourcetable.name.tostring(); %> <%string paramname=getparamname(tablename); %> <%string tabledescstring=gettabledescriptionname(sourcetable.description);%> @using abp.web.mvc.extensions @using <%=rootnamespace%>.web.bundling @using <%=rootnamespace%>.abpzerotemplate @{ localizationsourcename = abpzerotemplateconsts.localizationsourcename; } @section styles { @*@html.includestyle("~/libs/bootstrap-daterangepicker/daterangepicker.css")*@ } @section scripts { @*@html.includescript(scriptpaths.angular_daterangepicker)*@ } <div> @*//mark 1*@ <form name="<%=paramname%>createoreditform" role="form" novalidate class="form-validation"> <div class="modal-header"> <h4 class="modal-title"> <span ng-if="vm.<%=paramname%>.id">编辑信息:{{vm.<%=paramname%>.name}}</span> <span ng-if="!vm.<%=paramname%>.id">新增信息</span> </h4> </div> <div class="modal-body"> /* 两列模板 <div class="row"> <div class="col-sm-6"> //单列的具体代码1 </div> <div class="col-sm-6"> //单列的具体代码2 </div> </div> */ <% foreach (columnschema column in sourcetable.columns) { %> <% if(column.size>100) {%> <div class="form-group form-md-line-input form-md-floating-label no-hint"> <textarea auto-focus class="form-control" name="<%=getparamname(column.name)%>" style="resize: none;" ng-class="{'edited':vm.<%=paramname%>.<%=getparamname(column.name)%>}" ng-model="vm.<%=paramname%>.<%=getparamname(column.name)%>" required ng-pattern="{填写具体正则表达式}" ng-minlength="10" ng-maxlength="<%=column.size%>"></textarea> <label><%=column.description%></label> </div> <div ng-messages="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error" ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error"> <ul class="help-block text-danger"> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.pattern" ng-message="pattern"><%=column.description%>格式不正确{具体自己再次更改}!</li> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.required" ng-message="required"><%=column.description%>不能为空!</li> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.minlength" ng-message="minlength"><%=column.description%>最小长度为10!</li> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.maxlength" ng-message="maxlength"><%=column.description%>最大长度为<%=column.size%>!</li> </ul> </div> <%}else {%> <div class="form-group form-md-line-input form-md-floating-label no-hint"> <input type="text" class="form-control" name="<%=getparamname(column.name)%>" ng-class="{'edited':vm.<%=paramname%>.<%=getparamname(column.name)%>}" ng-pattern="{填写具体正则表达式}" ng-model="vm.<%=paramname%>.<%=getparamname(column.name)%>" required ng-minlength="10" ng-maxlength="<%=column.size%>" /> <label><%=column.description%></label> </div> <div ng-messages="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error" ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error"> <ul class="help-block text-danger"> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.pattern" ng-message="pattern"><%=column.description%>格式不正确{具体自己再次更改}!</li> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.required" ng-message="required"><%=column.description%>不能为空!</li> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.minlength" ng-message="minlength"><%=column.description%>最小长度为10!</li> <li ng-show="<%=paramname%>createoreditform.<%=getparamname(column.name)%>.$error.maxlength" ng-message="maxlength"><%=column.description%>最大长度为<%=column.size%>!</li> </ul> </div> <% }%> <% } %> </div> <div class="modal-footer"> <button ng-disabled="vm.saving" type="button" class="btn btn-default" ng-click="vm.cancel()">@l("cancel")</button> <button type="submit" button-busy="vm.saving" busy-text="@l("savingwiththreedot")" class="btn btn-primary blue" ng-click="vm.save()" ng-disabled="<%=paramname%>createoreditform.$invalid"><i class="fa fa-save"></i> <span>@l("save")</span></button> </div> </form> </div> <script runat="template"> <!-- #include file="../templateutilities.cs" --> </script>
结果局部展示
model 实体
using system; using abp.authorization.users; using abp.extensions; using microsoft.aspnet.identity; using system.componentmodel.dataannotations.schema; using abp.domain.entities; using system.threading.tasks; using system.componentmodel.dataannotations; using system.componentmodel; using abp; //---------------------------------------------- //简介:hashblockchain.zldb_domain entity 数据库对应实体 // // // //auther: //---------------------------------------------- namespace hashblockchain.zldb_domain { //获取主键id的命名 ///链信息表 [table("chaininfo")] public partial class chaininfo : entity<int> { #region declarations /// <summary> /// 链名称 /// </summary> [displayname("链名称")] [stringlength(30)] public virtual string chainname { get; set; } /// <summary> /// 链id /// </summary> [displayname("链id")] [stringlength(30)] public virtual string chainid { get; set; } /// <summary> /// 链描述 /// </summary> [displayname("链描述")] [stringlength(200)] public virtual string chaindescription { get; set; } /// <summary> /// 链状态 /// </summary> public virtual int? chainstatus { get; set; } /// <summary> /// 排序 /// </summary> public virtual int? sort { get; set; } /// <summary> /// 是否可见 /// </summary> public virtual bool? isenabled { get; set; } /// <summary> /// 创建人 /// </summary> public virtual int? createuserid { get; set; } /// <summary> /// 创建时间 /// </summary> public virtual datetime? createdatetime { get; set; } /// <summary> /// 最后一次修改人 /// </summary> public virtual int? lastedituserid { get; set; } /// <summary> /// 最后一次修改时间 /// </summary> public virtual datetime? lasteditdatetime { get; set; } /// <summary> /// 节点个数 /// </summary> public virtual int? peercount { get; set; } /// <summary> /// 区块链高度 /// </summary> public virtual long? blockheight { get; set; } #endregion } }
中英文 中文显示
部分权限生成的代码
上一篇: Java Web开发之访问路径问题分析
下一篇: C语言实现数字炸弹小游戏
推荐阅读
-
springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
-
java 快速开发框架平台 二次开发 代码生成器 springmvc SSM后台框架源码
-
springboot 后台框架平台 mybatis 集成代码生成器 shiro 权限 websocket
-
springboot mybatis 项目框架源码 shiro 集成代码生成器 ehcache缓存
-
spring cloud springboot 框架源码 activiti工作流 前后分离 集成代码生成器
-
ABP 框架代码批量生成器
-
springboot activiti 工作流版本 集成代码生成器 shiro 安全框架
-
代码框架生成器
-
springboot mybatis 后台框架平台 集成代码生成器 shiro 权限
-
java SSM框架 代码生成器 快速开发平台 websocket即时通讯 shiro redis