欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ABP 框架代码批量生成器

程序员文章站 2022-04-15 11:20:49
需要最新源码,或技术提问,请加QQ群:538327407,由于源码在不断完善,会在之后同步到开源项目中 简介 用abp 框架快两年了,用它完成了多个项目,作为CTO同时也作为架构师,在应对中小型项目时候,我们通常选择ABP(内部大型的物联网架构采用自己的框架),感觉这款框架真心不错。虽然开源社区有也 ......

 

需要最新源码,或技术提问,请加qq群:538327407,由于源码在不断完善,会在之后同步到开源项目中

简介

用abp 框架快两年了,用它完成了多个项目,作为cto同时也作为架构师,在应对中小型项目时候,我们通常选择abp(内部大型的物联网架构采用自己的框架),感觉这款框架真心不错。虽然开源社区有也有很多写了几套代码生成器,但是我用完之后,总是感觉不能达到我自己想要的效果,我个人还是比较喜欢一步到位,批量生成,所以就写了这套基于codesmith的代码生成器,这一套在项目中还算稳定。

 

模板介绍 

先看一下代码结构

ABP 框架代码批量生成器

 

 我们的项目中我规划使用的是spa的,所以一般会生成常规 四个目录,分别是如下

 

ABP 框架代码批量生成器

 

 

其余的中英文,还有权限、以及dbcontext 部分相对数量比较少,统一改造,生成单个文件进行copy。

最后使用templatebuid 自动生成上面的批量文件。

 

代码解析和使用

每个代码生成器部分需要先配置对应的项目名称,和model等,细节需要自己去了解

 

ABP 框架代码批量生成器

 

 常规简单操作

 

一般需要我们用powerdesign等设计工具,设计好对应的表,标注要注释,先临时生成一个数据库,通过codesmith 生成代码后,在通过code first 形式,真正在abp 对应的数据库中生成数据库表。

 以下文件是templatebuid.cst 文件,配置完成后,

ABP 框架代码批量生成器

 

生成代码操作,先编译,后生成。

ABP 框架代码批量生成器

 

 详细代码举例说明

 

由于篇幅有限,我就简单说明一下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>

 

结果局部展示

 ABP 框架代码批量生成器

ABP 框架代码批量生成器

 

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
    }
}

中英文 中文显示

 

ABP 框架代码批量生成器

 

部分权限生成的代码

 

ABP 框架代码批量生成器