需要最新源码,或技术提问,请加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
}
}

中英文 中文显示

部分权限生成的代码

读后感觉不错,有收获可以微信请作者喝杯咖啡,读后有疑问请加微信,拉群研讨,注明来意

最新文章

  1. 自定义tableViewCell
  2. CSS FIXED porn javhd
  3. 【转】CPU调度
  4. Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析
  5. [Swust OJ 1139]--Coin-row problem
  6. jsp页面格式化数字或时间
  7. redhat5安装phantomjs
  8. javascript中this的指向
  9. JavaScript实现ZLOGO: 用语法树实现多层循环
  10. Visual SVN Server启动失败0x8007042a错误
  11. 61.H5---利用canvas+原生js进行鼠标跟随绘图
  12. JavaScript实现页面刷新滚动条位置不变(利用cookie)
  13. 51nod--1265 四点共面 (计算几何基础, 点积, 叉积)
  14. Redis与RabbitMQ作为消息队列的比较
  15. mySQL 教程 第2章 安装和介绍mySQL
  16. linux - 文件拆分
  17. fzyzojP2984 -- 序列变换问题
  18. maven的pom报plugins缺失的解决方法
  19. mpvue笔记
  20. transient关键字的理解

热门文章

  1. Median(二分+二分)
  2. python的错误类型和异常处理
  3. struts2框架值栈的概述之问题一:什么是值栈?
  4. hg 添加用户
  5. Linux 磁盘分区存放文件和目录的数量 (inode)
  6. db2学习笔记
  7. cmd里面怎么复制粘贴
  8. linux 静态链接库demo
  9. Windows游戏找不到了怎么办?
  10. java读取网页图片路径并下载到本地