需要最新源码,或技术提问,请加QQ群:538327407

我的各种github 开源项目和代码:https://github.com/linbin524

简介

用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 类型做了不同代码输出

 <%@ 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="HashBlockChain" Optional="False" Category="1.名称空间" Description="系统名称空间的根名称." %>
<%@ Property Name="Namespace" Type="String" Default="ZLDB_Domain" Optional="False" Category="1.名称空间" Description="系统当前所属文件夹的名称(命名空间相关)." %>
<%@ Property Name="FolderNamespace" Type="String" Default="" Optional="true" Category="1.名称空间" Description="系统名称空间的Model名称." %>
<%@ Property Name="PrefixLength" Type="Int32" Default="" 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, "", ); %>
<% FolderNamespace=SourceTable.Name.ToString();%>
<%string tableName=SourceTable.Name.ToString(); %>
<%string paramName=GetParamName(tableName); %> using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Dynamic;
using Abp.Linq.Extensions;
using <%= RootNamespace %>.<%=Namespace%>.Dtos;
using <%= RootNamespace %>.Dto;
using <%= RootNamespace %>.Authorization.<%=tableName%>.Exporting;
namespace <%= RootNamespace %>.<%=Namespace%>
{ <% foreach (ColumnSchema column in SourceTable.Columns) { %>
<% if (column.IsPrimaryKeyMember) { %> <%string tempType = GetCSharpVariableType(column); %> <% if (tempType=="Guid") { %>
/// <summary>
/// <%=SourceTable.Description%> 业务实现接口
/// </summary>
public class <%=tableName%>AppService : AbpZeroTemplateAppServiceBase, I<%=tableName%>AppService
{
private readonly IRepository<<%=tableName%>, Guid> _<%=paramName%>Repository;
private readonly I<%=tableName%>ListExcelExporter _i<%=tableName%>ListExcelExporter; /// <summary>
/// 构造函数自动注入我们所需要的类或接口
/// </summary>
public <%=tableName%>AppService(IRepository<<%=tableName%>, Guid> <%=paramName%>Repository,I<%=tableName%>ListExcelExporter i<%=tableName%>ListExcelExporter)
{
_<%=paramName%>Repository = <%=paramName%>Repository;
_i<%=tableName%>ListExcelExporter = i<%=tableName%>ListExcelExporter; } /// <summary>
/// 获取所有数据列表
/// </summary>
/// <returns>返回数据集合</returns>
public async Task<List<<%=tableName%>Dto>> GetAllList()
{
//调用Task仓储的特定方法GetAllWithPeople
var resultList = await _<%=paramName%>Repository.GetAllListAsync();
return Mapper.Map<List<<%=tableName%>Dto>>(resultList).ToList();
} /// <summary>
/// 获取分页数据列表 分页具体代码需要适当修改,如orderby 需要匹配 创建时间 或者其他数据Id(int)
/// </summary>
/// <returns>返回数据集合</returns>
public async Task<PagedResultDto<<%=tableName%>Dto>> GetPagedListAsync(PagedAndFilteredInputDto input)
{
var query = _<%=paramName%>Repository.GetAll();
//TODO:根据传入的参数添加过滤条件 var resultCount = await query.CountAsync();
var result<%=paramName%> = await query
.OrderBy(x=>x.Id)
.PageBy(input)
.ToListAsync(); var resultListDtos = result<%=paramName%>.MapTo<List<<%=tableName%>Dto>>(); if (!string.IsNullOrEmpty(input.Sorting)) {
resultListDtos = resultListDtos.OrderBy(input.Sorting).ToList();
} return new PagedResultDto<<%=tableName%>Dto>(
resultCount,
resultListDtos
);
} /// <summary>
/// 获取指定条件的数据列表 webapi 无法使用
/// </summary>
/// <returns>返回数据集合</returns>
public async Task<List<<%=tableName%>Dto>> GetListByCodition(Expression<Func<<%=tableName%>, bool>> predicate)
{ var resultList = await _<%=paramName%>Repository.GetAllListAsync(predicate);
return Mapper.Map<List<<%=tableName%>Dto>>(resultList).ToList();
} /// <summary>
/// 导出excel 具体方法
/// </summary>
/// <returns>excel文件</returns>
/// public async Task<FileDto> Get<%=tableName%>ToExcel()
///{
/// var resultList = await _<%=paramName%>Repository.GetAllListAsync();
/// var <%=paramName%>Dtos= Mapper.Map<List<<%=tableName%>Dto>>(resultList).ToList();
/// return _i<%=tableName%>ListExcelExporter.ExportToFile(<%=paramName%>Dtos);
/// } /// <summary>
/// 根据指定id 获取数据实体
/// </summary>
/// <param name="input">当前id</param>
/// <returns></returns>
public async Task<<%=tableName%>Dto> Get<%=tableName%>ForEditAsync(NullableIdDto<System.Guid> input)
{
var output = new <%=tableName%>Dto(); <%=tableName%>Dto <%=paramName%>EditDto; if (input.Id.HasValue)
{
var entity = await _<%=paramName%>Repository.GetAsync(input.Id.Value);
<%=paramName%>EditDto = entity.MapTo<<%=tableName%>Dto>();
}
else
{
<%=paramName%>EditDto = new <%=tableName%>Dto();
} output = <%=paramName%>EditDto;
return output;
} /// <summary>
/// 根据Id创建或编辑操作
/// </summary>
/// <param name="input">实体</param>
/// <returns></returns>
public async Task CreateOrUpdate<%=tableName%>Async(<%=tableName%>Dto input)
{
if (!string.IsNullOrWhiteSpace(input.Id))
{
await Update(input);
}
else
{
await Create(input);
}
} /// <summary>
/// 新增
/// </summary>
/// <param name="input">新增参数</param>
/// <returns>新增实体</returns>
public async Task<Guid> Create(<%=tableName%>Dto input)
{
input.Id = new <%=tableName%>().Id.ToString();
var resultObj = input.MapTo<<%=tableName%>>();
var result = await _<%=paramName%>Repository.InsertAsync(resultObj); return result.Id;
} /// <summary>
/// 修改
/// </summary>
/// <param name="input">修改参数</param>
/// <returns>修改实体</returns>
public async Task<<%=tableName%>Dto> Update(<%=tableName%>Dto input)
{
<%=tableName%> obj = await _<%=paramName%>Repository.GetAsync(new Guid(input.Id));
input.MapTo(obj);
var result = await _<%=paramName%>Repository.UpdateAsync(obj);
return obj.MapTo<<%=tableName%>Dto>();
} /// <summary>
/// 删除
/// </summary>
/// <param name="input">删除Dto</param>
/// <returns>无返回值</returns>
public async System.Threading.Tasks.Task Delete(EntityDto<string> input)
{
await _<%=paramName%>Repository.DeleteAsync(new Guid(input.Id));
} /// <summary>
/// 删除 webapi 无法使用
/// </summary>
/// <param name="predicate">删除条件</param>
/// <returns>无返回值</returns>
public async System.Threading.Tasks.Task DeleteByCondition(Expression<Func<<%=tableName%>, bool>> predicate)
{
await _<%=paramName%>Repository.DeleteAsync(predicate); }
} <% } else {%>
/// <summary>
/// <%=SourceTable.Description%> 业务实现接口
/// </summary>
public class <%=tableName%>AppService : AbpZeroTemplateAppServiceBase, I<%=tableName%>AppService
{
private readonly IRepository<<%=tableName%>, <%=tempType%>> _<%=paramName%>Repository;
private readonly I<%=tableName%>ListExcelExporter _i<%=tableName%>ListExcelExporter; /// <summary>
/// 构造函数自动注入我们所需要的类或接口
/// </summary>
public <%=tableName%>AppService(IRepository<<%=tableName%>, <%=tempType%>> <%=paramName%>Repository,I<%=tableName%>ListExcelExporter i<%=tableName%>ListExcelExporter)
{
_<%=paramName%>Repository = <%=paramName%>Repository;
_i<%=tableName%>ListExcelExporter = i<%=tableName%>ListExcelExporter; } /// <summary>
/// 获取所有数据列表
/// </summary>
/// <returns>返回数据集合</returns>
public async Task<List<<%=tableName%>Dto>> GetAllList()
{
//调用Task仓储的特定方法GetAllWithPeople
var resultList = await _<%=paramName%>Repository.GetAllListAsync();
return Mapper.Map<List<<%=tableName%>Dto>>(resultList).ToList();
} /// <summary>
/// 获取分页数据列表 分页具体代码需要适当修改,如orderby 需要匹配 创建时间 或者其他数据Id(int)
/// </summary>
/// <returns>返回数据集合</returns>
public async Task<PagedResultDto<<%=tableName%>Dto>> GetPagedListAsync(PagedAndFilteredInputDto input)
{
var query = _<%=paramName%>Repository.GetAll();
//TODO:根据传入的参数添加过滤条件 var resultCount = await query.CountAsync();
var result<%=paramName%> = await query
.OrderBy(x=>x.Id)
.PageBy(input)
.ToListAsync(); var resultListDtos = result<%=paramName%>.MapTo<List<<%=tableName%>Dto>>();
return new PagedResultDto<<%=tableName%>Dto>(
resultCount,
resultListDtos
);
} /// <summary>
/// 获取指定条件的数据列表 webapi 无法使用
/// </summary>
/// <returns>返回数据集合</returns>
public async Task<List<<%=tableName%>Dto>> GetListByCodition(Expression<Func<<%=tableName%>, bool>> predicate)
{ var resultList = await _<%=paramName%>Repository.GetAllListAsync(predicate);
return Mapper.Map<List<<%=tableName%>Dto>>(resultList).ToList();
} /// <summary>
/// 导出excel 具体方法
/// </summary>
/// <returns>excel文件</returns>
/// public async Task<FileDto> Get<%=tableName%>ToExcel()
///{
/// var resultList = await _<%=paramName%>Repository.GetAllListAsync();
/// var <%=paramName%>Dtos= Mapper.Map<List<<%=tableName%>Dto>>(resultList).ToList();
/// return _i<%=tableName%>ListExcelExporter.ExportToFile(<%=paramName%>Dtos);
/// } /// <summary>
/// 根据指定id 获取数据实体
/// </summary>
/// <param name="input">当前id</param>
/// <returns></returns>
public async Task<<%=tableName%>Dto> Get<%=tableName%>ForEditAsync(NullableIdDto<<%=tempType%>> input)
{
var output = new <%=tableName%>Dto(); <%=tableName%>Dto <%=paramName%>EditDto; if (Convert.ToInt32(input.Id)>)
{
var entity = await _<%=paramName%>Repository.GetAsync(Convert.ToInt32(input.Id));
<%=paramName%>EditDto = entity.MapTo<<%=tableName%>Dto>();
}
else
{
<%=paramName%>EditDto = new <%=tableName%>Dto();
} output = <%=paramName%>EditDto;
return output;
} /// <summary>
/// 根据Id创建或编辑操作
/// </summary>
/// <param name="input">实体</param>
/// <returns></returns>
public async Task CreateOrUpdate<%=tableName%>Async(<%=tableName%>Dto input)
{
if (Convert.ToInt32(input.Id)>)
{
await Update(input);
}
else
{
await Create(input);
}
} /// <summary>
/// 新增
/// </summary>
/// <param name="input">新增参数</param>
/// <returns>新增实体</returns>
public async Task<<%=tempType%>> Create(<%=tableName%>Dto input)
{
input.Id = new <%=tableName%>().Id.ToString();
var resultObj = input.MapTo<<%=tableName%>>();
var result = await _<%=paramName%>Repository.InsertAsync(resultObj); return result.Id;
} /// <summary>
/// 修改
/// </summary>
/// <param name="input">修改参数</param>
/// <returns>修改实体</returns>
public async Task<<%=tableName%>Dto> Update(<%=tableName%>Dto input)
{
<%=tableName%> obj = await _<%=paramName%>Repository.GetAsync(Convert.ToInt32(input.Id));
input.MapTo(obj);
var result = await _<%=paramName%>Repository.UpdateAsync(obj);
return obj.MapTo<<%=tableName%>Dto>();
} /// <summary>
/// 删除
/// </summary>
/// <param name="input">删除Dto</param>
/// <returns>无返回值</returns>
public async System.Threading.Tasks.Task Delete(EntityDto<string> input)
{
await _<%=paramName%>Repository.DeleteAsync(Convert.ToInt32(input.Id));
} /// <summary>
/// 删除 webapi 无法使用
/// </summary>
/// <param name="predicate">删除条件</param>
/// <returns>无返回值</returns>
public async System.Threading.Tasks.Task DeleteByCondition(Expression<Func<<%=tableName%>, bool>> predicate)
{
await _<%=paramName%>Repository.DeleteAsync(predicate); }
} <% }%>
<% }%> <% }%> } <script runat="template">
<!-- #include file="TemplateUtilities.cs" -->
</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="" 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, "", ); %>
<%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>) {%>
<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="" 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="" 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()] public virtual string ChainName { get; set; } /// <summary>
/// 链Id
/// </summary>
[DisplayName("链Id")]
[StringLength()] public virtual string ChainId { get; set; } /// <summary>
/// 链描述
/// </summary>
[DisplayName("链描述")]
[StringLength()] 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 框架代码批量生成器的更多相关文章

  1. 利用代码生成工具生成基于ABP框架的代码

    在前面随笔,我介绍了整个ABP优化过框架的分层模型,包括尽量简化整个ABP框架的各个层的关系,以及纳入一些基类的辅助处理,使得我们对应业务分层类或者接口尽可能减少代码,并具有生产环境所需要的基类接口, ...

  2. 使用代码生成工具快速开发ABP框架项目

    在一般系统开发中,我们一般要借助于高度定制化的代码生成工具,用于统一代码风,节省开发时间,提高开发效率.不同的项目,它的项目不同分层的基类定义不同,我们需要在框架基类的基础上扩展我们的业务类代码,尽量 ...

  3. Mybatis-plus<一> Springboot框架使用MybatisPlus代码自动生成器

    Mybatis-plus<一> Springboot框架使用MybatisPlus代码自动生成器 Mybatis-plus官网: https://mp.baomidou.com/ Demo ...

  4. ABP框架个人开发实战(1)_环境搭建

    前言 之前关注ABP框架有一阵子了,一直没有潜下心来实际研究一下.最近想自己建站,以后有自己的功能开发项目,可以在自己的站点上开发,并一步步的完善,所以找个比较好用的框架迫在眉睫,选来选去,决定用AB ...

  5. 后台工作者HangFire与ABP框架Abp.Hangfire及扩展

    HangFire与Quartz.NET相比主要是HangFire的内置提供集成化的控制台,方便后台查看及监控,对于大家来说,比较方便. HangFire是什么 Hangfire是一个开源框架(.NET ...

  6. ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十四节--后台工作者HangFire与ABP框架Abp.Hangfire及扩展

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 HangFire与Quartz.NET相比主要是HangFire的内置提供集成化的控制台,方便后台查看及监控,对于 ...

  7. 使用ABP框架踩过的坑系列2

    ABP中有很多惯例,如果使用得当,可以事半功倍,如果使用不当,也会有很大的麻烦,是否适当其实还是要看Need需求 ASP.NET Boilerplate (ABP) is an open source ...

  8. ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理

    在前面两篇随笔<ABP开发框架前后端开发系列---(7)系统审计日志和登录日志的管理>和<ABP开发框架前后端开发系列---(8)ABP框架之Winform界面的开发过程>开始 ...

  9. [译]ABP框架v2.3.0已经发布!

    在新冠病毒的日子里,我们发布了ABP框架v2.3, 这篇文章将说明本次发布新增内容和过去的两周我们做了什么. 关于新冠病毒和我们的团队 关于冠状病毒的状况我们很难过.在Volosoft的团队,我们有不 ...

随机推荐

  1. forward(请求转发)和redirect(重定向)的区别

    原理: forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原 ...

  2. 没有无线路由,如何让手机使用电脑的网络xyytit

    前言: 智能手机已经越来越普遍,但国内的无线网络的步伐还是没有跟上智能机的脚步.纵使3G,4G已经相继推出,但国内的资费价格着实有点不接地气,所以无线wifi无疑是智能机使用最多的.各大软件上.设备商 ...

  3. TIME_WAIT状态的作用

    TIME_WAIT状态: 主动关闭的那端最后经历的状态,一般为2MSL秒(1~4分钟). 两个原因: 保证当最后一个ack丢失后,能收到对端重传的fin包. 保证ack包消失,不会影响下一个连接. 关 ...

  4. swift和OC - 拆分数组 和 拆分字符串

    1. 拆分数组 /// 根据 数组 截取 指定个数返回 多个数组的集合 func splitArray( array: [Date], withSubSize subSize: Int) -> ...

  5. struts框架值栈问题二之值栈的内部结构

    2. 问题二 : 值栈的内部结构 ? * 值栈由两部分组成 > root -- Struts把动作和相关对象压入 ObjectStack 中--List > context -- Stru ...

  6. MySql中4种批量更新的方法

    最近在完成MySql项目集成的情况下,需要增加批量更新的功能,根据网上的资料整理了一下,很好用,都测试过,可以直接使用. mysql 批量更新共有以下四种办法 1..replace into 批量更新 ...

  7. Codeforces 710C. Magic Odd Square n阶幻方

    C. Magic Odd Square time limit per test:1 second memory limit per test:256 megabytes input:standard ...

  8. [远程] windows 2008 server设置了共享文件夹,并且共享给了everyone,但是还是无法访问,怎么解决呢?

    还需要设置另外一个地方,将用户加到MSAppAccess这个组里去

  9. struts2乱码问题

    简介:做了个功能,用的struts2,表单提交到后台,接收后打印出来的数据乱码.   解决步骤: 1. struts.xml中配置<constant name="struts.i18n ...

  10. 利用windows.h头文件写一个简单的C语言倒计时

    今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...