├── .gitignore ├── Poepon.AbpCodeGenerator.Core ├── IServiceProviderExtensions.cs ├── Models │ ├── MetaColumnInfo.cs │ ├── MetaTableInfo.cs │ ├── euColumnType.cs │ └── euControlType.cs ├── Poepon.AbpCodeGenerator.Core.csproj ├── Poepon.AbpCodeGenerator.Core.csproj.user ├── Properties │ └── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Resources │ ├── Application.ico │ ├── favicon.ico │ └── otheroptions.ico ├── Scaffolders │ ├── AreaScaffolder.cs │ ├── AreaScaffolderFactory.cs │ ├── DtoScaffolder.cs │ ├── KingsWebDtoDescription.cs │ ├── ModuleScaffolder.cs │ └── ModuleScaffolderFactory.cs ├── Templates │ └── ABPScaffolder │ │ ├── CSharpHelpers.t4 │ │ ├── Module.t4 │ │ ├── Web.t4 │ │ ├── {AppName}.Application │ │ └── {EntityFolerName} │ │ │ ├── Dto │ │ │ ├── CreateOrUpdate{Entity}Input.cs.t4 │ │ │ ├── Get{Entity}ForEditOutput.cs.t4 │ │ │ ├── Get{Entity}ListInput.cs.t4 │ │ │ ├── {Entity}EditDto.cs.t4 │ │ │ └── {Entity}ListDto.cs.t4 │ │ │ ├── I{Entity}AppService.cs.t4 │ │ │ └── {Entity}AppService.cs.t4 │ │ ├── {AppName}.Common │ │ ├── AdminNavigationProvider.cs.t4 │ │ └── AppPermissions.cs.t4 │ │ ├── {AppName}.Core │ │ └── IRepositories │ │ │ └── I{Entity}Repository.cs.t4 │ │ ├── {AppName}.EntityFramework │ │ └── EntityFramework │ │ │ └── Repositories │ │ │ └── {Entity}Repository.cs.t4 │ │ └── {AppName}.Web │ │ ├── Areas │ │ └── {Module} │ │ │ ├── Controllers │ │ │ └── {PluralEntityName}Controller.cs.t4 │ │ │ ├── Models │ │ │ └── {PluralEntityName} │ │ │ │ └── CreateOrEdit{Entity}ModalViewModel.cs.t4 │ │ │ └── Views │ │ │ └── {PluralEntityName} │ │ │ ├── Index.cshtml.t4 │ │ │ └── _CreateOrEditModal.cshtml.t4 │ │ └── wwwroot │ │ └── view-resources │ │ └── Areas │ │ └── {Module} │ │ └── Views │ │ └── {PluralEntityName} │ │ ├── Index.js.t4 │ │ ├── _CreateOrEditModal.js.t4 │ │ └── index.less.t4 ├── UI │ ├── BindBehavior.cs │ ├── DelegateCommand.cs │ ├── DtoClassMemberSetting.xaml │ ├── DtoClassMemberSetting.xaml.cs │ ├── FocusBehavior.cs │ ├── GeneratorAreaDialog.xaml │ ├── GeneratorAreaDialog.xaml.cs │ ├── GeneratorAreaViewModel.cs │ ├── GeneratorModuleDialog.xaml │ ├── GeneratorModuleDialog.xaml.cs │ ├── GeneratorModuleViewModel.cs │ ├── MethodType.cs │ ├── ModelMetadataViewModel.cs │ ├── ModelType.cs │ ├── VSPlatformDialogWindow.cs │ ├── ViewFormSetting.xaml │ ├── ViewFormSetting.xaml.cs │ ├── ViewModel.cs │ └── ViewModelOfT.cs ├── Utils │ ├── ProjectItemUtils.cs │ ├── StorageMan.cs │ ├── VisualStudioUtils.cs │ └── VmUtils.cs ├── VsConstants.cs ├── app.config └── packages.config ├── Poepon.AbpCodeGenerator.VSIX ├── Poepon.AbpCodeGenerator.VSIX.csproj ├── Poepon.AbpCodeGenerator.VSIX.csproj.user ├── Properties │ └── AssemblyInfo.cs ├── index.html ├── source.extension.vsixmanifest └── stylesheet.css ├── Poepon.AbpCodeGenerator.sln └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 3 | ################################################################################ 4 | 5 | /packages 6 | /.vs/Poepon.AbpCodeGenerator/v14 7 | /.vs 8 | /Poepon.AbpCodeGenerator.Core/bin/Release 9 | /Poepon.AbpCodeGenerator.Core/obj/Release 10 | /Poepon.AbpCodeGenerator.VSIX/bin/Release 11 | /Poepon.AbpCodeGenerator.VSIX/obj/Release 12 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/IServiceProviderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Poepon.AbpCodeGenerator.Core 4 | { 5 | internal static class IServiceProviderExtensions 6 | { 7 | public static TService GetService(this IServiceProvider provider) where TService : class 8 | { 9 | if (provider == null) 10 | { 11 | throw new ArgumentNullException("provider"); 12 | } 13 | 14 | return (TService)provider.GetService(typeof(TService)); 15 | } 16 | 17 | public static bool IsServiceAvailable(this IServiceProvider provider) where TService : class 18 | { 19 | if (provider == null) 20 | { 21 | throw new ArgumentNullException("provider"); 22 | } 23 | 24 | return GetService(provider) != null; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Models/MetaColumnInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using EnvDTE; 4 | using Poepon.AbpCodeGenerator.Core.Utils; 5 | 6 | namespace Poepon.AbpCodeGenerator.Core.Models 7 | { 8 | [Serializable] 9 | public class MetaColumnInfo 10 | { 11 | public string ShortTypeName { get; set; } 12 | public string strDataType { get; set; } 13 | public euColumnType DataType { get; set; } 14 | public euControlType ControlType { get; set; } 15 | public string Name { get; set; } 16 | public string DisplayName { get; set; } 17 | public bool Nullable { get; set; } 18 | public bool Required { get; set; } 19 | public int? MaxLength { get; set; } 20 | public int? RangeMin { get; set; } 21 | public int? RangeMax { get; set; } 22 | 23 | public bool IsDtoVisible { get; set; } 24 | public bool IsItemVisible { get; set; } 25 | 26 | public bool IsNumeric 27 | { 28 | get { return ((this.DataType & euColumnType.intCT) == euColumnType.intCT); } 29 | } 30 | 31 | public bool HasMetaAttribute 32 | { 33 | get 34 | { 35 | return (MetaAttribute != string.Empty); 36 | } 37 | } 38 | 39 | public string MetaAttribute 40 | { 41 | get 42 | { 43 | switch (this.DataType) 44 | { 45 | case euColumnType.stringCT: 46 | //if (this.MaxLength > 0) 47 | if (this.MaxLength.HasValue) 48 | return string.Format("[MaxLength({0})]", this.MaxLength); 49 | else 50 | break; 51 | case euColumnType.longCT: 52 | case euColumnType.intCT: 53 | case euColumnType.decimalCT: 54 | case euColumnType.floatCT: 55 | case euColumnType.doubleCT: 56 | //if (this.RangeMin > 0 || this.RangeMax > 0) 57 | if (this.RangeMin.HasValue || this.RangeMax.HasValue) 58 | return string.Format("[Range({0}, {1})]", this.RangeMin, this.RangeMax); 59 | else 60 | break; 61 | default: 62 | break; 63 | } 64 | return string.Empty; 65 | } 66 | } 67 | 68 | 69 | //public MetaColumnInfo() { } 70 | 71 | //public MetaColumnInfo(Microsoft.AspNet.Scaffolding.Core.Metadata.PropertyMetadata property) 72 | // : this(property.PropertyName, property.PropertyName, property.ShortTypeName, (property.RelatedModel != null)) 73 | //{ 74 | //} 75 | 76 | //public MetaColumnInfo(CodeParameter property) 77 | // : this(property.Name, property.DocComment, property.Type.AsString, false) 78 | //{ 79 | //} 80 | 81 | //public MetaColumnInfo(CodeProperty property) 82 | // : this(property.Name, property.DocComment, property.Type.AsString, false) 83 | //{ 84 | //} 85 | 86 | //private MetaColumnInfo(string strName, string strDisplayName, string strType, bool relatedModel) 87 | //{ 88 | // this.Name = strName; 89 | // this.ShortTypeName = strType; 90 | // this.strDataType = strType.Replace("?", "").Replace("System.", "").ToLower(); 91 | 92 | // if (!relatedModel) 93 | // { 94 | // this.DataType = GetColumnType(this.strDataType); 95 | // IsVisible = true; 96 | // } 97 | // else 98 | // { 99 | // this.DataType = euColumnType.RelatedModel; 100 | // IsVisible = false; //不勾选导航属性 101 | // } 102 | 103 | // DisplayName = strDisplayName ?? this.Name; 104 | // Nullable = true; 105 | //} 106 | 107 | 108 | public MetaColumnInfo(CodeProperty property) 109 | { 110 | string strName = property.Name; 111 | string strType = property.Type.AsString; 112 | string strDisplayName = VmUtils.getCName(property); 113 | this.Name = property.Name; 114 | this.ShortTypeName = property.Type.AsString; 115 | //this.strDataType = strType.Replace("?", "").Replace("System.", "").ToLower(); 116 | //this.strDataType = strType.Replace("System.", ""); 117 | this.strDataType = strType.Split('.').Last(); 118 | this.DataType = GetColumnType(strType); 119 | DisplayName = strDisplayName ?? this.Name; 120 | Nullable = true; 121 | Required = false; 122 | setPropWithAttributes(property); 123 | if (strDataType.ToLower() == "int" || strDataType.ToLower() == "guid") 124 | { 125 | Nullable = false; 126 | } 127 | this.ControlType = GetControlType(); //放在setPropWithAttributes之后 128 | 129 | IsDtoVisible = IsDtoVisibleMember(); 130 | IsItemVisible = IsItemVisibleMember(); 131 | } 132 | 133 | private bool IsDtoVisibleMember() 134 | { 135 | if (DataType == euColumnType.RelatedModel) return false; 136 | if (VmUtils.DtoUnSelectFields.Contains(Name)) return false; 137 | return true; 138 | } 139 | 140 | private bool IsItemVisibleMember() 141 | { 142 | if (DataType == euColumnType.RelatedModel) return false; 143 | if (VmUtils.ItemUnSelectFields.Contains(Name)) return false; 144 | if (DataType == euColumnType.stringCT && !MaxLength.HasValue) return false; //没有字符数限制的string 145 | return true; 146 | } 147 | 148 | private void setPropWithAttributes(CodeProperty property) 149 | { 150 | foreach (var ele in property.Attributes) 151 | { 152 | var prop = ele as CodeAttribute; 153 | if (prop.Name == "Required") 154 | { 155 | this.Required = true; 156 | this.Nullable = false; 157 | } 158 | if (prop.Name == "MaxLength") 159 | { 160 | int v = 0; 161 | int.TryParse(prop.Value, out v); 162 | this.MaxLength = v; 163 | } 164 | if (prop.Name == "Range") 165 | { 166 | var arr = prop.Value.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); 167 | int n1 = 0, n2 = 0; 168 | int.TryParse(arr[0], out n1); 169 | int.TryParse(arr[1], out n2); 170 | this.RangeMin = n1; 171 | this.RangeMax = n2; 172 | } 173 | } 174 | } 175 | 176 | public euColumnType GetColumnType(string shortTypeName) 177 | { 178 | return ParseEnum(shortTypeName); 179 | } 180 | 181 | public euControlType GetControlType() 182 | { 183 | if (Name.EndsWith("Id") && DataType == euColumnType.guidCT) 184 | return euControlType.DropdownList; 185 | 186 | if (Name == "Summary" || Name == "Remark") 187 | return euControlType.Textarea; 188 | 189 | if (Name == "Content") 190 | return euControlType.Textarea; 191 | 192 | if (DataType == euColumnType.boolCT) 193 | return euControlType.Checkbox; 194 | 195 | if (DataType == euColumnType.datetimeCT) 196 | return euControlType.DateTimePicker; 197 | 198 | if (DataType == euColumnType.stringCT && !MaxLength.HasValue) 199 | return euControlType.Textarea; 200 | 201 | return euControlType.Text; 202 | } 203 | 204 | //private static T ParseEnum(string value) 205 | //{ 206 | // value = value+ "CT"; 207 | // return (T)Enum.Parse(typeof(T), value, true); 208 | //} 209 | 210 | //private static T ParseEnum2(string value) 211 | //{ 212 | // value = value + "CT"; 213 | // T result; 214 | // if (Enum.TryParse(value, true, out result)) 215 | // { 216 | // return result; 217 | // } 218 | // else 219 | // return default(T); 220 | //} 221 | 222 | private static euColumnType ParseEnum(string value) 223 | { 224 | value = value.Replace("?", "").Replace("System.", "").ToLower() + "CT"; 225 | euColumnType result; 226 | if (Enum.TryParse(value, true, out result)) 227 | { 228 | return result; 229 | } 230 | else 231 | return euColumnType.RelatedModel; 232 | } 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Models/MetaTableInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Poepon.AbpCodeGenerator.Core.Models 6 | { 7 | [Serializable] 8 | public class MetaTableInfo 9 | { 10 | public List Columns { get; set; } 11 | 12 | public MetaColumnInfo this[string name] 13 | { 14 | get { return this.Columns.FirstOrDefault(x => x.Name == name); } 15 | } 16 | public MetaColumnInfo this[int index] 17 | { 18 | get { return this.Columns[index]; } 19 | } 20 | 21 | public MetaTableInfo() 22 | { 23 | this.Columns = new List(); 24 | } 25 | 26 | 27 | //public static MetadataTableinfo ToDataModel(ModelMetadataViewModel vm) 28 | //{ 29 | // MetadataTableinfo model = new MetadataTableinfo(); 30 | // model.Columns = new List(); 31 | // foreach (MetadataFieldViewModel c1 in vm.Columns) 32 | // { 33 | // model.Columns.Add(c1.DataModel); 34 | // } 35 | // return model; 36 | //} 37 | 38 | //public ModelMetadataViewModel ToViewModel(MetadataTableinfo data) 39 | //{ 40 | // ModelMetadataViewModel vm = new ModelMetadataViewModel(); 41 | // vm. 42 | //} 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Models/euColumnType.cs: -------------------------------------------------------------------------------- 1 | namespace Poepon.AbpCodeGenerator.Core.Models 2 | { 3 | public enum euColumnType 4 | { 5 | /// 6 | /// int 7 | /// 8 | intCT = 0x1 9 | , 10 | /// 11 | /// decimal 12 | /// 13 | decimalCT = 0x3 14 | , 15 | /// 16 | /// decimal 17 | /// 18 | longCT = 0x5 19 | , 20 | /// 21 | /// float 22 | /// 23 | floatCT = 0x7 24 | , 25 | /// 26 | /// double 27 | /// 28 | doubleCT = 0x9 29 | , 30 | /// 31 | /// string 32 | /// 33 | stringCT = 0x0 34 | , 35 | /// 36 | /// DateTime 37 | /// 38 | datetimeCT = 0x2 39 | , 40 | boolCT = 0x4 41 | , 42 | guidCT = 0x10 43 | , 44 | /// 45 | /// RelatedModel 46 | /// 47 | RelatedModel = 0x20 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Models/euControlType.cs: -------------------------------------------------------------------------------- 1 | namespace Poepon.AbpCodeGenerator.Core.Models 2 | { 3 | public enum euControlType 4 | { 5 | Text, 6 | Textarea, 7 | TextEditor, 8 | Hidden, 9 | DatePicker, 10 | DateTimePicker, 11 | DropdownList, 12 | Checkbox 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Poepon.AbpCodeGenerator.Core.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ShowAllFiles 5 | 6 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Poepon.AbpCodeGenerator.Core")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Poepon.AbpCodeGenerator.Core")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("98874bcf-dbc1-452f-a208-90dae5e116fd")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Poepon.AbpCodeGenerator.Core { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Poepon.AbpCodeGenerator.Core.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 使用此强类型资源类,为所有资源查找 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Icon Application { 67 | get { 68 | object obj = ResourceManager.GetObject("Application", resourceCulture); 69 | return ((System.Drawing.Icon)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// 查找类似 不需要描述了 的本地化字符串。 75 | /// 76 | internal static string MVCScaffolder_Description { 77 | get { 78 | return ResourceManager.GetString("MVCScaffolder_Description", resourceCulture); 79 | } 80 | } 81 | 82 | /// 83 | /// 查找类似 不需要描述 的本地化字符串。 84 | /// 85 | internal static string MVCScaffolder_Description2 { 86 | get { 87 | return ResourceManager.GetString("MVCScaffolder_Description2", resourceCulture); 88 | } 89 | } 90 | 91 | /// 92 | /// 查找类似 生成MVC5增删改查 的本地化字符串。 93 | /// 94 | internal static string MVCScaffolder_Name { 95 | get { 96 | return ResourceManager.GetString("MVCScaffolder_Name", resourceCulture); 97 | } 98 | } 99 | 100 | /// 101 | /// 查找类似 生成列表查询 的本地化字符串。 102 | /// 103 | internal static string MVCScaffolder_Name2 { 104 | get { 105 | return ResourceManager.GetString("MVCScaffolder_Name2", resourceCulture); 106 | } 107 | } 108 | 109 | /// 110 | /// 查找类似 添加新的data context... 的本地化字符串。 111 | /// 112 | internal static string WebFormsCodeGeneratorViewModel_AddNewDbContext { 113 | get { 114 | return ResourceManager.GetString("WebFormsCodeGeneratorViewModel_AddNewDbContext", resourceCulture); 115 | } 116 | } 117 | 118 | /// 119 | /// 查找类似 不能加载的Model类型。如果项目没有编译,请编译后重试。 的本地化字符串。 120 | /// 121 | internal static string WebFormsScaffolder_ProjectNotBuilt { 122 | get { 123 | return ResourceManager.GetString("WebFormsScaffolder_ProjectNotBuilt", resourceCulture); 124 | } 125 | } 126 | 127 | /// 128 | /// 查找类似 请选择一个有效的 DbContext 类。 的本地化字符串。 129 | /// 130 | internal static string WebFormsScaffolder_SelectDbContextType { 131 | get { 132 | return ResourceManager.GetString("WebFormsScaffolder_SelectDbContextType", resourceCulture); 133 | } 134 | } 135 | 136 | /// 137 | /// 查找类似 请选择一个有效的 Model 类。 的本地化字符串。 138 | /// 139 | internal static string WebFormsScaffolder_SelectModelType { 140 | get { 141 | return ResourceManager.GetString("WebFormsScaffolder_SelectModelType", resourceCulture); 142 | } 143 | } 144 | 145 | /// 146 | /// 查找类似 需要先调用ShowUIAndValidate方法。 的本地化字符串。 147 | /// 148 | internal static string WebFormsScaffolder_ShowUIAndValidateNotCalled { 149 | get { 150 | return ResourceManager.GetString("WebFormsScaffolder_ShowUIAndValidateNotCalled", resourceCulture); 151 | } 152 | } 153 | 154 | /// 155 | /// 查找类似 Action名称不可为空 的本地化字符串。 156 | /// 157 | internal static string WebFormsViewScaffolder_EmptyActionName { 158 | get { 159 | return ResourceManager.GetString("WebFormsViewScaffolder_EmptyActionName", resourceCulture); 160 | } 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | Resources\favicon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | 不需要描述了 126 | 127 | 128 | 不需要描述 129 | 130 | 131 | 生成MVC5增删改查 132 | 133 | 134 | 生成列表查询 135 | 136 | 137 | 添加新的data context... 138 | 139 | 140 | 不能加载的Model类型。如果项目没有编译,请编译后重试。 141 | 142 | 143 | 请选择一个有效的 DbContext 类。 144 | 145 | 146 | 请选择一个有效的 Model 类。 147 | 148 | 149 | 需要先调用ShowUIAndValidate方法。 150 | 151 | 152 | Action名称不可为空 153 | 154 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Resources/Application.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Poepon/AbpCodeGenerator/61e12ec167530d8d7dc525236cd335d5b25aae21/Poepon.AbpCodeGenerator.Core/Resources/Application.ico -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Resources/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Poepon/AbpCodeGenerator/61e12ec167530d8d7dc525236cd335d5b25aae21/Poepon.AbpCodeGenerator.Core/Resources/favicon.ico -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Resources/otheroptions.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Poepon/AbpCodeGenerator/61e12ec167530d8d7dc525236cd335d5b25aae21/Poepon.AbpCodeGenerator.Core/Resources/otheroptions.ico -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Scaffolders/AreaScaffolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Windows.Input; 6 | using EnvDTE; 7 | using Microsoft.AspNet.Scaffolding; 8 | using Poepon.AbpCodeGenerator.Core.UI; 9 | using Poepon.AbpCodeGenerator.Core.Utils; 10 | 11 | namespace Poepon.AbpCodeGenerator.Core.Scaffolders 12 | { 13 | // 此类包含基架生成的所有步骤: 14 | // 1) ShowUIAndValidate() - 显示一个Visual Studio的对话框用于设置生成参数 15 | // 2) Validate() - 确认提取的Model validates the model collected from the dialog 16 | // 3) GenerateCode() - 根据模板生成代码文件 if all goes well, generates the scaffolding output from the templates 17 | public class AreaScaffolder : CodeGenerator 18 | { 19 | 20 | private GeneratorAreaViewModel _moduleViewModel; 21 | 22 | internal AreaScaffolder(CodeGenerationContext context, CodeGeneratorInformation information) 23 | : base(context, information) 24 | { 25 | 26 | } 27 | 28 | public override bool ShowUIAndValidate() 29 | { 30 | _moduleViewModel = new GeneratorAreaViewModel(Context); 31 | 32 | GeneratorAreaDialog window = new GeneratorAreaDialog(_moduleViewModel); 33 | bool? isOk = window.ShowModal(); 34 | 35 | if (isOk == true) 36 | { 37 | Validate(); 38 | } 39 | return (isOk == true); 40 | } 41 | 42 | 43 | // Validates the model returned by the Visual Studio dialog. 44 | // We always force a Visual Studio build so we have a model 45 | private void Validate() 46 | { 47 | if (_moduleViewModel.ModelType == null) 48 | { 49 | throw new InvalidOperationException("请选择一个有效的实体类。"); 50 | } 51 | 52 | if (_moduleViewModel.DtoClass == null) 53 | { 54 | throw new InvalidOperationException("未找到实体类对应的Dto类。"); 55 | } 56 | 57 | if (_moduleViewModel.ItemClass == null) 58 | { 59 | throw new InvalidOperationException("未找到实体类对应的QueryDto类。"); 60 | } 61 | 62 | if (string.IsNullOrWhiteSpace(_moduleViewModel.FunctionName)) 63 | { 64 | throw new InvalidOperationException("请填写功能中文名称"); 65 | } 66 | 67 | 68 | } 69 | 70 | public override void GenerateCode() 71 | { 72 | if (_moduleViewModel == null) 73 | { 74 | throw new InvalidOperationException("需要先调用ShowUIAndValidate方法。"); 75 | } 76 | 77 | Cursor currentCursor = Mouse.OverrideCursor; 78 | try 79 | { 80 | Mouse.OverrideCursor = Cursors.Wait; 81 | 82 | var project = Context.ActiveProject; 83 | var entity = _moduleViewModel.ModelType.CodeType; 84 | var entityName = entity.Name; 85 | var entityNamespace = entity.Namespace.FullName; 86 | var entityFolerName = ProjectItemUtils.GetModuleName(entityNamespace); 87 | var puralEntityName = VmUtils.ToPlural(entityName); 88 | var projectNamespace = ProjectItemUtils.GetProjectName(entityNamespace); 89 | var overwrite = _moduleViewModel.OverwriteFiles; 90 | Dictionary templateParams = new Dictionary(){ 91 | {"AppName", projectNamespace} 92 | , {"EntityNamespace", entityNamespace} 93 | , {"EntityFolerName",entityFolerName} 94 | , {"PluralEntityName",puralEntityName} 95 | , {"EntityName", entityName} 96 | , {"DtoNamespace", _moduleViewModel.DtoNamespace} 97 | , {"FunctionName", _moduleViewModel.FunctionName} 98 | , {"DtoMetaTable", _moduleViewModel.DtoClassMetadataViewModel.DataModel} 99 | , {"ItemMetaTable", _moduleViewModel.ItemClassMetadataViewModel.DataModel} 100 | }; 101 | 102 | var templates = new[] 103 | { 104 | @"{AppName}.Web\Areas\{Module}\Controllers\{PluralEntityName}Controller.cs", 105 | @"{AppName}.Web\Areas\{Module}\Models\{PluralEntityName}\CreateOrEdit{Entity}ModalViewModel.cs", 106 | @"{AppName}.Web\Areas\{Module}\Views\{PluralEntityName}\_CreateOrEditModal.cshtml", 107 | @"{AppName}.Web\Areas\{Module}\Views\{PluralEntityName}\Index.cshtml", 108 | @"{AppName}.Web\wwwroot\view-resources\Areas\{Module}\Views\{PluralEntityName}\_CreateOrEditModal.js", 109 | @"{AppName}.Web\wwwroot\view-resources\Areas\{Module}\Views\{PluralEntityName}\Index.js", 110 | @"{AppName}.Web\wwwroot\view-resources\Areas\{Module}\Views\{PluralEntityName}\index.less", 111 | @"{AppName}.Common\{PluralEntityName}PageNames.cs", 112 | }; 113 | foreach (var template in templates) 114 | { 115 | string outputPath = Path.GetFileNameWithoutExtension(Path.Combine(@"_GeneratedCode\", 116 | template.Replace("{AppName}", projectNamespace) 117 | .Replace("{Module}", "Admin") 118 | .Replace("{PluralEntityName}", puralEntityName) 119 | .Replace("{Entity}", entityName))); 120 | 121 | string templatePath = Path.Combine(template); 122 | 123 | AddFileFromTemplate(project, outputPath, templatePath, templateParams, !overwrite); 124 | } 125 | } 126 | finally 127 | { 128 | Mouse.OverrideCursor = currentCursor; 129 | } 130 | } 131 | 132 | protected new bool AddFileFromTemplate(Project project, string outputPath, string templateName, 133 | IDictionary templateParameters, bool skipIfExists) 134 | { 135 | if (project == null) 136 | throw new ArgumentNullException("project"); 137 | if (templateParameters == null) 138 | throw new ArgumentNullException("templateParameters"); 139 | var service1 = this.ServiceProvider.GetService(); 140 | var service2 = this.ServiceProvider.GetService(); 141 | string filePath = Path.GetFileNameWithoutExtension(templateName); 142 | string fileExtension = Path.GetExtension(templateName); 143 | string textTemplatePath = service1.GetTextTemplatePath(filePath, this.TemplateFolders, fileExtension); 144 | string str = Path.GetDirectoryName(project.DTE.Solution.FullName).TrimEnd('\\') + "\\"; 145 | 146 | if (textTemplatePath.StartsWith(str, StringComparison.OrdinalIgnoreCase)) 147 | { 148 | AddTelemetryData(this.Context, "MSInternal_CoreInfo", "IsCustomTemplate", true); 149 | } 150 | 151 | return service2.AddFileFromTemplate(project, outputPath, textTemplatePath, templateParameters, skipIfExists); 152 | } 153 | 154 | public static void AddTelemetryData(CodeGenerationContext context, string producerId, string key, object value) 155 | { 156 | if (context == null) 157 | throw new ArgumentNullException("context"); 158 | if (producerId == null) 159 | throw new ArgumentNullException("producerId"); 160 | if (key == null) 161 | throw new ArgumentNullException("key"); 162 | if (value == null) 163 | throw new ArgumentNullException("value"); 164 | GetItems(context, producerId)[key] = value; 165 | } 166 | 167 | private static Dictionary GetItems(CodeGenerationContext context, string producerId) 168 | { 169 | Dictionary property; 170 | if (!context.Items.TryGetProperty(producerId, out property)) 171 | { 172 | property = new Dictionary(); 173 | context.Items.AddProperty(producerId, property); 174 | } 175 | return property; 176 | } 177 | 178 | 179 | private void WriteLog(string str) 180 | { 181 | File.AppendAllText("D:\\Scaffolder.log.txt", str + "\r\n"); 182 | } 183 | 184 | 185 | 186 | #region function library 187 | 188 | 189 | // Called to ensure that the project was compiled successfully 190 | private Type GetReflectionType(string typeName) 191 | { 192 | return GetService().GetType(Context.ActiveProject, typeName); 193 | } 194 | 195 | private TService GetService() where TService : class 196 | { 197 | return (TService)ServiceProvider.GetService(typeof(TService)); 198 | } 199 | 200 | 201 | // Returns the relative path of the folder selected in Visual Studio or an empty 202 | // string if no folder is selected. 203 | protected string GetSelectionRelativePath() 204 | { 205 | return Context.ActiveProjectItem == null ? String.Empty : ProjectItemUtils.GetProjectRelativePath(Context.ActiveProjectItem); 206 | } 207 | 208 | #endregion 209 | 210 | 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Scaffolders/AreaScaffolderFactory.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Poepon/AbpCodeGenerator/61e12ec167530d8d7dc525236cd335d5b25aae21/Poepon.AbpCodeGenerator.Core/Scaffolders/AreaScaffolderFactory.cs -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Scaffolders/DtoScaffolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Windows.Input; 6 | using EnvDTE; 7 | using Microsoft.AspNet.Scaffolding; 8 | using Poepon.AbpCodeGenerator.Core.UI; 9 | using Poepon.AbpCodeGenerator.Core.Utils; 10 | 11 | namespace Poepon.AbpCodeGenerator.Core.Scaffolders 12 | { 13 | public class DtoScaffolder: CodeGenerator 14 | { 15 | private GeneratorModuleViewModel _moduleViewModel; 16 | internal DtoScaffolder(CodeGenerationContext context, CodeGeneratorInformation information) 17 | : base(context, information) 18 | { 19 | 20 | } 21 | 22 | public override bool ShowUIAndValidate() 23 | { 24 | _moduleViewModel = new GeneratorModuleViewModel(Context); 25 | 26 | GeneratorModuleDialog window = new GeneratorModuleDialog(_moduleViewModel); 27 | bool? isOk = window.ShowModal(); 28 | 29 | if (isOk == true) 30 | { 31 | Validate(); 32 | } 33 | return (isOk == true); 34 | } 35 | 36 | 37 | // Validates the model returned by the Visual Studio dialog. 38 | // We always force a Visual Studio build so we have a model 39 | private void Validate() 40 | { 41 | CodeType modelType = _moduleViewModel.ModelType.CodeType; 42 | 43 | if (modelType == null) 44 | { 45 | throw new InvalidOperationException("请选择一个有效的Dto类。"); 46 | } 47 | 48 | var visualStudioUtils = new VisualStudioUtils(); 49 | visualStudioUtils.BuildProject(Context.ActiveProject); 50 | 51 | 52 | Type reflectedModelType = GetReflectionType(modelType.FullName); 53 | if (reflectedModelType == null) 54 | { 55 | throw new InvalidOperationException("不能加载的Dto类型。如果项目没有编译,请编译后重试。"); 56 | } 57 | } 58 | 59 | public override void GenerateCode() 60 | { 61 | if (_moduleViewModel == null) 62 | { 63 | throw new InvalidOperationException("需要先调用ShowUIAndValidate方法。"); 64 | } 65 | 66 | Cursor currentCursor = Mouse.OverrideCursor; 67 | try 68 | { 69 | Mouse.OverrideCursor = Cursors.Wait; 70 | 71 | generateCode(); 72 | } 73 | finally 74 | { 75 | Mouse.OverrideCursor = currentCursor; 76 | } 77 | } 78 | 79 | 80 | private void generateCode() 81 | { 82 | var project = Context.ActiveProject; 83 | var entity = _moduleViewModel.ModelType.CodeType; 84 | var entityName = entity.Name; 85 | var projectNamespace = project.GetDefaultNamespace(); 86 | var entityNamespace = entity.Namespace.FullName; 87 | var moduleNamespace = getModuleNamespace(entityNamespace); 88 | var moduleName = getModuleName(moduleNamespace); 89 | var functionName = _moduleViewModel.FunctionName; 90 | var isDisplayOrderable = IsDisplayOrderable(entity); 91 | var overwrite = _moduleViewModel.OverwriteFiles; 92 | 93 | Dictionary templateParams = new Dictionary(){ 94 | {"ProjectNamespace", projectNamespace} 95 | , {"EntityNamespace", entityNamespace} 96 | , {"ModuleNamespace", moduleNamespace} 97 | , {"ModuleName", moduleName} 98 | , {"EntityName", entityName} 99 | , {"FunctionName", functionName} 100 | , {"DtoMetaTable", _moduleViewModel.DtoClassMetadataViewModel.DataModel} 101 | , {"IsDisplayOrderable", isDisplayOrderable} 102 | }; 103 | 104 | var templates = new[] { 105 | @"Application\{FunctionFolderName}\Dtos\{Entity}Dto" 106 | , @"Application\{FunctionFolderName}\Dtos\{Entity}QueryDto" 107 | , @"Application\{FunctionFolderName}\Dtos\Get{Entity}QueryInput" 108 | , @"Application\{FunctionFolderName}\I{Entity}AppService" 109 | , @"Application\{FunctionFolderName}\{Entity}AppService" 110 | , @"Application\{FunctionFolderName}\_{Entity}Permissions" 111 | , @"Domain\{FunctionFolderName}\Repositories\I{Entity}Repository" 112 | , @"Repository\{FunctionFolderName}\Repositories\{Entity}Repository" 113 | }; 114 | 115 | foreach (var template in templates) 116 | { 117 | string outputPath = Path.Combine(@"_GeneratedCode\" + moduleName, template.Replace("{Entity}", entityName)); 118 | 119 | string templatePath = Path.Combine(@"Module", template); 120 | //WriteLog("outputPath:" + outputPath); 121 | //WriteLog("templatePath:" + templatePath); 122 | AddFileFromTemplate(project, outputPath, templatePath, templateParams, !overwrite); 123 | } 124 | 125 | } 126 | 127 | private void WriteLog(string str) 128 | { 129 | File.AppendAllText("D:\\Scaffolder.log.txt", str + "\r\n"); 130 | } 131 | 132 | private bool IsDisplayOrderable(CodeType entity) 133 | { 134 | return entity.IsDerivedType("Abp.Domain.Entities.IDisplayOrderable"); 135 | } 136 | 137 | private string getModuleNamespace(string entityNamespace) 138 | { 139 | var list = entityNamespace.Split('.').ToList(); 140 | if (entityNamespace.Contains("YMC.Entities.")) //YMC.Entities.Content 141 | { 142 | return "YMC.ECCentral." + list[2]; 143 | } 144 | if (list.Contains("Domain")) //命名空间包含Domain时, 去除Domain以后的 145 | { 146 | int index = list.IndexOf("Domain"); 147 | if (index > 0) 148 | { 149 | list.RemoveRange(index, list.Count - index); 150 | } 151 | } 152 | return string.Join(".", list); 153 | } 154 | 155 | private string getModuleName(string moduleNamespace) 156 | { 157 | return moduleNamespace.Split('.').Last(); 158 | } 159 | 160 | 161 | #region function library 162 | 163 | 164 | // Called to ensure that the project was compiled successfully 165 | private Type GetReflectionType(string typeName) 166 | { 167 | return GetService().GetType(Context.ActiveProject, typeName); 168 | } 169 | 170 | private TService GetService() where TService : class 171 | { 172 | return (TService)ServiceProvider.GetService(typeof(TService)); 173 | } 174 | 175 | 176 | // Returns the relative path of the folder selected in Visual Studio or an empty 177 | // string if no folder is selected. 178 | protected string GetSelectionRelativePath() 179 | { 180 | return Context.ActiveProjectItem == null ? String.Empty : ProjectItemUtils.GetProjectRelativePath(Context.ActiveProjectItem); 181 | } 182 | 183 | #endregion 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Scaffolders/KingsWebDtoDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | using System.Runtime.Versioning; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows; 9 | using System.Windows.Interop; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using Microsoft.AspNet.Scaffolding; 13 | 14 | namespace Poepon.AbpCodeGenerator.Core.Scaffolders 15 | { 16 | public class KingsWebDtoDescription : CodeGeneratorFactory 17 | { 18 | public KingsWebDtoDescription() 19 | : base(CreateCodeGeneratorInformation()) 20 | { 21 | 22 | } 23 | public override ICodeGenerator CreateInstance(CodeGenerationContext context) 24 | { 25 | return new DtoScaffolder(context, Information); 26 | } 27 | 28 | // We support CSharp WAPs targetting at least .Net Framework 4.5 or above. 29 | // We DON'T currently support VB 30 | public override bool IsSupported(CodeGenerationContext codeGenerationContext) 31 | { 32 | if (ProjectLanguage.CSharp.Equals(codeGenerationContext.ActiveProject.GetCodeLanguage())) 33 | { 34 | FrameworkName targetFramework = codeGenerationContext.ActiveProject.GetTargetFramework(); 35 | return (targetFramework != null) && 36 | String.Equals(".NetFramework", targetFramework.Identifier, StringComparison.OrdinalIgnoreCase) && 37 | targetFramework.Version >= new Version(4, 5); 38 | } 39 | 40 | return false; 41 | } 42 | 43 | private static CodeGeneratorInformation CreateCodeGeneratorInformation() 44 | { 45 | return new CodeGeneratorInformation( 46 | displayName: "获取Dto文档", 47 | description: "前端人员获取Dto文档", 48 | author: "寒飞", 49 | version: new Version(0, 1, 0, 0), 50 | id: "ABPScaffolder", 51 | icon: ToImageSource(Resources.Application), 52 | gestures: new[] { "YMC" }, 53 | categories: new[] { "YMC", Categories.Common, Categories.Other } 54 | ); 55 | } 56 | 57 | /// 58 | /// Helper method to convert Icon to Imagesource. 59 | /// 60 | /// Icon 61 | /// Imagesource 62 | public static ImageSource ToImageSource(Icon icon) 63 | { 64 | ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon( 65 | icon.Handle, 66 | Int32Rect.Empty, 67 | BitmapSizeOptions.FromEmptyOptions()); 68 | 69 | return imageSource; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Scaffolders/ModuleScaffolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Windows.Input; 6 | using EnvDTE; 7 | using Microsoft.AspNet.Scaffolding; 8 | using Poepon.AbpCodeGenerator.Core.UI; 9 | using Poepon.AbpCodeGenerator.Core.Utils; 10 | 11 | namespace Poepon.AbpCodeGenerator.Core.Scaffolders 12 | { 13 | // 此类包含基架生成的所有步骤: 14 | // 1) ShowUIAndValidate() - 显示一个Visual Studio的对话框用于设置生成参数 15 | // 2) Validate() - 确认提取的Model validates the model collected from the dialog 16 | // 3) GenerateCode() - 根据模板生成代码文件 if all goes well, generates the scaffolding output from the templates 17 | public class ModuleScaffolder : CodeGenerator 18 | { 19 | 20 | private GeneratorModuleViewModel _moduleViewModel; 21 | 22 | internal ModuleScaffolder(CodeGenerationContext context, CodeGeneratorInformation information) 23 | : base(context, information) 24 | { 25 | 26 | } 27 | 28 | public override bool ShowUIAndValidate() 29 | { 30 | _moduleViewModel = new GeneratorModuleViewModel(Context); 31 | 32 | GeneratorModuleDialog window = new GeneratorModuleDialog(_moduleViewModel); 33 | bool? isOk = window.ShowModal(); 34 | 35 | if (isOk == true) 36 | { 37 | Validate(); 38 | } 39 | return (isOk == true); 40 | } 41 | 42 | 43 | // Validates the model returned by the Visual Studio dialog. 44 | // We always force a Visual Studio build so we have a model 45 | private void Validate() 46 | { 47 | CodeType modelType = _moduleViewModel.ModelType.CodeType; 48 | 49 | if (modelType == null) 50 | { 51 | throw new InvalidOperationException("请选择一个有效的实体类。"); 52 | } 53 | 54 | //var visualStudioUtils = new VisualStudioUtils(); 55 | //visualStudioUtils.BuildProject(Context.ActiveProject); 56 | 57 | } 58 | private string GetEntityPrimaryKeyType(CodeType codeType) 59 | { 60 | string[] strBaseType = { 61 | "Abp.Domain.Entities.IEntity", 62 | "Abp.Domain.Entities.IEntity", 63 | "Abp.Domain.Entities.IEntity", 64 | "Abp.Domain.Entities.IEntity", 65 | "Abp.Domain.Entities.IEntity" 66 | }; 67 | if (codeType.IsDerivedType("Abp.Domain.Entities.Entity") || codeType.IsDerivedType("Abp.Domain.Entities.IEntity") || codeType.IsDerivedType("Abp.Domain.Entities.IEntity")) 68 | { 69 | return "int"; 70 | } 71 | else if (codeType.IsDerivedType(strBaseType[0])) 72 | { 73 | return "Guid"; 74 | } 75 | else if (codeType.IsDerivedType(strBaseType[1])) 76 | { 77 | return "long"; 78 | } 79 | else if (codeType.IsDerivedType(strBaseType[2])) 80 | { 81 | return "DateTime"; 82 | } 83 | else if (codeType.IsDerivedType(strBaseType[3])) 84 | { 85 | return "short"; 86 | } 87 | else if (codeType.IsDerivedType(strBaseType[4])) 88 | { 89 | return "string"; 90 | } 91 | else 92 | { 93 | return "int"; 94 | } 95 | } 96 | public override void GenerateCode() 97 | { 98 | if (_moduleViewModel == null) 99 | { 100 | throw new InvalidOperationException("需要先调用ShowUIAndValidate方法。"); 101 | } 102 | 103 | Cursor currentCursor = Mouse.OverrideCursor; 104 | try 105 | { 106 | Mouse.OverrideCursor = Cursors.Wait; 107 | var project = Context.ActiveProject; 108 | var entity = _moduleViewModel.ModelType.CodeType; 109 | 110 | var entityPrimaryKeyType = "int"; 111 | entityPrimaryKeyType = GetEntityPrimaryKeyType(entity); 112 | var entityName = entity.Name; 113 | var entityNamespace = entity.Namespace.FullName; 114 | 115 | var projectNamespace = ProjectItemUtils.GetProjectName(entityNamespace); 116 | var functionName = _moduleViewModel.FunctionName; 117 | var pluralEntityName = VmUtils.ToPlural(entityName); 118 | var entityFolerName = ProjectItemUtils.GetModuleName(entityNamespace); 119 | var overwrite = _moduleViewModel.OverwriteFiles; 120 | 121 | Dictionary templateParams = new Dictionary() 122 | { 123 | {"AppName", projectNamespace} 124 | , 125 | {"EntityNamespace", entityNamespace} 126 | , 127 | {"EntityName", entityName} 128 | , 129 | {"EntityPrimaryKeyType", entityPrimaryKeyType} 130 | , 131 | {"EntityFolerName", entityFolerName} 132 | , 133 | {"PluralEntityName", pluralEntityName} 134 | , 135 | {"FunctionName", functionName} 136 | , 137 | {"DtoMetaTable", _moduleViewModel.DtoClassMetadataViewModel.DataModel} 138 | }; 139 | 140 | var templates = new[] 141 | { 142 | @"{AppName}.Application\{EntityFolerName}\Dto\{Entity}EditDto.cs", 143 | @"{AppName}.Application\{EntityFolerName}\Dto\{Entity}ListDto.cs", 144 | @"{AppName}.Application\{EntityFolerName}\Dto\CreateOrUpdate{Entity}Input.cs", 145 | @"{AppName}.Application\{EntityFolerName}\Dto\Get{Entity}ForEditOutput.cs", 146 | @"{AppName}.Application\{EntityFolerName}\Dto\Get{Entity}ListInput.cs", 147 | @"{AppName}.Application\{EntityFolerName}\{Entity}AppService.cs", 148 | @"{AppName}.Application\{EntityFolerName}\I{Entity}AppService.cs", 149 | @"{AppName}.Common\{Entity}Common.cs", 150 | @"{AppName}.Core\IRepositories\I{Entity}Repository.cs", 151 | @"{AppName}.EntityFramework\EntityFramework\Repositories\{Entity}Repository.cs" 152 | }; 153 | foreach (var template in templates) 154 | { 155 | string outputPath = Path.GetFileNameWithoutExtension(Path.Combine(@"_GeneratedCode\", template.Replace("{AppName}", projectNamespace) 156 | .Replace("{EntityFolerName}", entityFolerName) 157 | .Replace("{Entity}", entityName))); 158 | 159 | string templatePath = Path.Combine(template); 160 | 161 | AddFileFromTemplate(project, outputPath, templatePath, templateParams, !overwrite); 162 | } 163 | } 164 | finally 165 | { 166 | Mouse.OverrideCursor = currentCursor; 167 | } 168 | } 169 | 170 | protected new bool AddFileFromTemplate(Project project, string outputPath, string templateName, 171 | IDictionary templateParameters, bool skipIfExists) 172 | { 173 | if (project == null) 174 | throw new ArgumentNullException("project"); 175 | if (templateParameters == null) 176 | throw new ArgumentNullException("templateParameters"); 177 | var service1 = this.ServiceProvider.GetService(); 178 | var service2 = this.ServiceProvider.GetService(); 179 | string filePath = Path.GetFileNameWithoutExtension(templateName); 180 | string fileExtension = Path.GetExtension(templateName); 181 | 182 | string textTemplatePath = service1.GetTextTemplatePath(filePath, this.TemplateFolders, fileExtension); 183 | string str = Path.GetDirectoryName(project.DTE.Solution.FullName).TrimEnd('\\') + "\\"; 184 | 185 | if (textTemplatePath.StartsWith(str, StringComparison.OrdinalIgnoreCase)) 186 | { 187 | AddTelemetryData(this.Context, "MSInternal_CoreInfo", "IsCustomTemplate", true); 188 | } 189 | 190 | return service2.AddFileFromTemplate(project, outputPath, textTemplatePath, templateParameters, skipIfExists); 191 | } 192 | 193 | public static void AddTelemetryData(CodeGenerationContext context, string producerId, string key, object value) 194 | { 195 | if (context == null) 196 | throw new ArgumentNullException("context"); 197 | if (producerId == null) 198 | throw new ArgumentNullException("producerId"); 199 | if (key == null) 200 | throw new ArgumentNullException("key"); 201 | if (value == null) 202 | throw new ArgumentNullException("value"); 203 | GetItems(context, producerId)[key] = value; 204 | } 205 | 206 | private static Dictionary GetItems(CodeGenerationContext context, string producerId) 207 | { 208 | Dictionary property; 209 | if (!context.Items.TryGetProperty>((object)producerId, out property)) 210 | { 211 | property = new Dictionary(); 212 | context.Items.AddProperty((object)producerId, (object)property); 213 | } 214 | return property; 215 | } 216 | 217 | 218 | 219 | private void WriteLog(string str) 220 | { 221 | File.AppendAllText("D:\\Scaffolder.log.txt", str + "\r\n"); 222 | } 223 | #region function library 224 | 225 | 226 | 227 | 228 | 229 | // Returns the relative path of the folder selected in Visual Studio or an empty 230 | // string if no folder is selected. 231 | protected string GetSelectionRelativePath() 232 | { 233 | return Context.ActiveProjectItem == null ? String.Empty : ProjectItemUtils.GetProjectRelativePath(Context.ActiveProjectItem); 234 | } 235 | 236 | #endregion 237 | 238 | 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Scaffolders/ModuleScaffolderFactory.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Poepon/AbpCodeGenerator/61e12ec167530d8d7dc525236cd335d5b25aae21/Poepon.AbpCodeGenerator.Core/Scaffolders/ModuleScaffolderFactory.cs -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/CSharpHelpers.t4: -------------------------------------------------------------------------------- 1 | <#+ 2 | public string ToCamelCase(string str) 3 | { 4 | if (string.IsNullOrWhiteSpace(str)) 5 | { 6 | return str; 7 | } 8 | 9 | if (str.Length == 1) 10 | { 11 | return str.ToLower(); 12 | } 13 | 14 | return char.ToLower(str[0]) + str.Substring(1); 15 | } 16 | 17 | public string GetColAttr(MetaColumnInfo col) 18 | { 19 | var colName = col.Name.ToLower(); 20 | var strDataType = col.strDataType.ToLower(); 21 | var ret = ""; 22 | if (colName.EndsWith("isactive")){ 23 | return ", width: \"80px\", className: \"center\", render: abp.grid.renderIsActive"; 24 | } 25 | else if (colName.EndsWith("picurl")){ 26 | return ", width: \"120px\", render: abp.grid.renderImg('100px', 'auto')"; 27 | } 28 | else if (strDataType.StartsWith("datetime")){ 29 | if (colName.EndsWith("date")){ 30 | return ", width: \"100px\", render: abp.grid.renderDate"; 31 | } 32 | else { 33 | return ", width: \"180px\", render: abp.grid.renderDateTime"; 34 | } 35 | } 36 | else if (strDataType.StartsWith("bool")){ 37 | return ", width: \"60px\", className: \"center\", render: abp.grid.renderBool"; 38 | } 39 | 40 | return ret; 41 | } 42 | 43 | public string GetFormControlLabel(MetaColumnInfo col) 44 | { 45 | var lbl = col.DisplayName + ":"; 46 | if (col.Required) 47 | lbl += "*"; 48 | return lbl; 49 | } 50 | 51 | public string GetFormControlValue(MetaColumnInfo col) 52 | { 53 | var str = col.Name; 54 | if (col.strDataType.ToLower().StartsWith("datetime")) 55 | str += ".ToShortString()"; 56 | return str; 57 | } 58 | 59 | public string GetFormControlCssClass(MetaColumnInfo col) 60 | { 61 | var str = ""; 62 | if (col.Required) 63 | str = " required"; 64 | if (col.strDataType.ToLower().StartsWith("datetime")) 65 | str += " date-picker"; 66 | return str; 67 | } 68 | 69 | public string GetFormRequiredAsterisk(MetaColumnInfo col) 70 | { 71 | if (col.Required) 72 | return "*"; 73 | return ""; 74 | } 75 | 76 | public string GetFormControlRequired(MetaColumnInfo col) 77 | { 78 | if (col.Required) 79 | return " data-rule-required=\"true\""; 80 | return ""; 81 | } 82 | 83 | public string GetFormControlMaxlength(MetaColumnInfo col) 84 | { 85 | if (col.MaxLength.HasValue) 86 | return string.Format(" maxlength=\"{0}\"", col.MaxLength); 87 | return ""; 88 | } 89 | 90 | public string GetFormControlHelpText(MetaColumnInfo col) 91 | { 92 | var list = new List(); 93 | if (col.Required){ 94 | list.Add("必填"); 95 | } 96 | if (col.MaxLength.HasValue){ 97 | list.Add(string.Format("不超过{0}个字", col.MaxLength)); 98 | } 99 | return string.Join(",", list); 100 | } 101 | 102 | public string GetDropDownListColName(MetaColumnInfo col) 103 | { 104 | var str = col.Name.Substring(0, col.Name.Length - 2) + "List"; 105 | return str; 106 | } 107 | 108 | public bool IsDropDownCol(MetaColumnInfo col){ 109 | if (IsGuidCol(col) && col.Name.EndsWith("Id")){ 110 | return true; 111 | } 112 | return false; 113 | } 114 | 115 | public bool IsGuidCol(MetaColumnInfo col){ 116 | return col.strDataType.ToLower().StartsWith("guid"); 117 | } 118 | 119 | public bool IsFullWidthCol(MetaColumnInfo column){ 120 | return column.ControlType == euControlType.Textarea || column.ControlType == euControlType.TextEditor; 121 | } 122 | 123 | public void WriteColControl(MetaColumnInfo column, string indent) 124 | { 125 | if (column.ControlType == euControlType.Textarea) { #> 126 | <#= indent #> 127 | <#+ } else if (column.ControlType == euControlType.TextEditor) { #> 128 | <#= indent #> 129 | <#+ } else if (column.ControlType == euControlType.DropdownList) { #> 130 | <#= indent #> @Html.DropDownList("<#= column.Name #>", new SelectList(ViewBag.<#= GetDropDownListColName(column) #>, "Id", "Title", Model.<#= column.Name #>)<#= column.Nullable ? ", \"\"": "" #>, new { @class = "form-control w300<#= GetFormControlCssClass(column) #>" }) 131 | <#+ } else if (column.ControlType == euControlType.Checkbox) { #> 132 | <#= indent #> 133 | <#+ } else if (column.ControlType == euControlType.Hidden) { #> 134 | <#= indent #> value="@Model.<#= GetFormControlValue(column) #>" /> 135 | <#+ } else if (column.ControlType == euControlType.DateTimePicker) { #> 136 | <#= indent #> value="@Model.<#= GetFormControlValue(column) #>" /> 137 | <#+ } else if (column.ControlType == euControlType.DatePicker) { #> 138 | <#= indent #> value="@Model.<#= GetFormControlValue(column) #>" /> 139 | <#+ } else { #> 140 | <#= indent #> value="@Model.<#= GetFormControlValue(column) #>" /> 141 | <#+ 142 | } 143 | } 144 | #> -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/Module.t4: -------------------------------------------------------------------------------- 1 | <#@ assembly name="System.Core" #> 2 | <#@ assembly name="System.Data.Linq" #> 3 | <#@ ScaffoldingAssembly Processor="ScaffoldingAssemblyLoader" #> 4 | <#@ import namespace="System.Collections" #> 5 | <#@ import namespace="System.Collections.Generic" #> 6 | <#@ import namespace="System.Linq" #> 7 | <#@ import namespace="Microsoft.AspNet.Scaffolding.Core.Metadata" #> 8 | <#@ import namespace="Poepon.AbpCodeGenerator.Core.Models" #> 9 | <#@ parameter type="System.String" name="AppName" #> 10 | <#@ parameter type="System.String" name="EntityFolerName" #> 11 | <#@ parameter type="System.String" name="PluralEntityName" #> 12 | <#@ parameter type="System.String" name="EntityNamespace" #> 13 | <#@ parameter type="System.String" name="EntityName" #> 14 | <#@ parameter type="System.String" name="EntityPrimaryKeyType" #> 15 | <#@ parameter type="System.String" name="FunctionName" #> 16 | <#@ parameter type="Poepon.AbpCodeGenerator.Core.Models.MetaTableInfo" name="DtoMetaTable" #> -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/Web.t4: -------------------------------------------------------------------------------- 1 | <#@ assembly name="System.Core" #> 2 | <#@ assembly name="System.Data.Linq" #> 3 | <#@ ScaffoldingAssembly Processor="ScaffoldingAssemblyLoader" #> 4 | <#@ import namespace="System.Collections" #> 5 | <#@ import namespace="System.Collections.Generic" #> 6 | <#@ import namespace="System.Linq" #> 7 | <#@ import namespace="Microsoft.AspNet.Scaffolding.Core.Metadata" #> 8 | <#@ import namespace="Poepon.AbpCodeGenerator.Core.Models" #> 9 | <#@ parameter type="System.String" name="AppName" #> 10 | <#@ parameter type="System.String" name="EntityFolerName" #> 11 | <#@ parameter type="System.String" name="PluralEntityName" #> 12 | <#@ parameter type="System.String" name="EntityNamespace" #> 13 | <#@ parameter type="System.String" name="EntityName" #> 14 | <#@ parameter type="System.String" name="EntityPrimaryKeyType" #> 15 | <#@ parameter type="System.String" name="FunctionName" #> 16 | <#@ parameter type="System.String" name="DtoNamespace" #> 17 | <#@ parameter type="Poepon.AbpCodeGenerator.Core.Models.MetaTableInfo" name="DtoMetaTable" #> -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Application/{EntityFolerName}/Dto/CreateOrUpdate{Entity}Input.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace <#= AppName #>.<#=EntityFolerName#>.Dto 7 | { 8 | public class CreateOrUpdate<#= EntityName #>Input 9 | { 10 | [Required] 11 | public <#= EntityName #>EditDto <#= EntityName #> { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Application/{EntityFolerName}/Dto/Get{Entity}ForEditOutput.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | 5 | namespace <#= AppName #>.<#=EntityFolerName#>.Dto 6 | { 7 | public class Get<#=EntityName#>ForEditOutput 8 | { 9 | public <#=EntityName#>EditDto <#=EntityName#> { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Application/{EntityFolerName}/Dto/Get{Entity}ListInput.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | using Abp.Runtime.Validation; 5 | using <#=AppName#>.Dto; 6 | namespace <#= AppName #>.<#=EntityFolerName#>.Dto 7 | { 8 | public class Get<#=EntityName#>ListInput : PagedAndSortedInputDto, IShouldNormalize 9 | { 10 | /// 11 | /// 规格化输入参数值 12 | /// 13 | public virtual void Normalize() 14 | { 15 | if (string.IsNullOrEmpty(Sorting)) 16 | { 17 | Sorting = "Id"; 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Application/{EntityFolerName}/Dto/{Entity}EditDto.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | using System; 5 | using System.ComponentModel.DataAnnotations; 6 | using Abp.Application.Services.Dto; 7 | using Abp.Domain.Entities; 8 | using Abp.Domain.Entities.Auditing; 9 | using Abp.AutoMapper; 10 | using <#= EntityNamespace #>; 11 | 12 | namespace <#= AppName #>.<#=EntityFolerName#>.Dto 13 | { 14 | <# 15 | if (!string.IsNullOrWhiteSpace(FunctionName)){ 16 | #> 17 | /// 18 | /// <#= FunctionName #> 19 | /// 20 | <# 21 | } 22 | #> 23 | [AutoMap(typeof(<#= EntityName #>))] 24 | public class <#= EntityName #>EditDto : EntityDto<<#=EntityPrimaryKeyType#>?> 25 | { 26 | <# 27 | foreach (MetaColumnInfo column in DtoMetaTable.Columns) { 28 | if (!column.IsDtoVisible) continue; 29 | #> 30 | <# 31 | if (column.DisplayName != column.Name){ 32 | #> 33 | /// 34 | /// <#= column.DisplayName #> 35 | /// 36 | <# 37 | } 38 | #> 39 | <# 40 | if (column.Required){ 41 | #> 42 | [Required] 43 | <# } 44 | 45 | if (column.HasMetaAttribute){ 46 | #> 47 | <#= column.MetaAttribute #> 48 | <# 49 | } 50 | #> 51 | public <#= column.strDataType #> <#= column.Name #> { get; set; } 52 | 53 | <# 54 | } 55 | #> 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Application/{EntityFolerName}/Dto/{Entity}ListDto.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | using System; 5 | using Abp.Domain.Entities; 6 | using Abp.Domain.Entities.Auditing; 7 | using Abp.Application.Services.Dto; 8 | using Abp.AutoMapper; 9 | using <#= EntityNamespace #>; 10 | 11 | namespace <#= AppName #>.<#=EntityFolerName#>.Dto 12 | { 13 | <# 14 | if (!string.IsNullOrWhiteSpace(FunctionName)){ 15 | #> 16 | /// 17 | /// <#= FunctionName #> 18 | /// 19 | <# 20 | } 21 | #> 22 | [AutoMap(typeof(<#= EntityName #>))] 23 | public class <#= EntityName #>ListDto : EntityDto<<#=EntityPrimaryKeyType#>> 24 | { 25 | <# 26 | foreach (MetaColumnInfo column in DtoMetaTable.Columns) { 27 | if (!column.IsDtoVisible) continue; 28 | #> 29 | <# 30 | if (column.DisplayName != column.Name){ 31 | #> 32 | /// 33 | /// <#= column.DisplayName #> 34 | /// 35 | <# 36 | } 37 | #> 38 | public <#= column.strDataType #> <#= column.Name #> { get; set; } 39 | <# 40 | } 41 | #> 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Application/{EntityFolerName}/I{Entity}AppService.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Threading.Tasks; 7 | using Abp.Application.Services; 8 | using Abp.Application.Services.Dto; 9 | using <#= AppName #>.<#=EntityFolerName#>.Dto; 10 | namespace <#= AppName #>.<#=EntityFolerName#> 11 | { 12 | public interface I<#= EntityName #>AppService : IApplicationService 13 | { 14 | #region <#= FunctionName #>管理 15 | 16 | /// 17 | /// 根据查询条件获取<#= FunctionName #>分页列表 18 | /// 19 | TaskListDto>> Get<#= EntityName #>PagedList(Get<#= EntityName #>ListInput input); 20 | 21 | /// 22 | /// 根据查询条件获取<#= FunctionName #>列表 23 | /// 24 | TaskListDto>> Get<#= EntityName #>List(Get<#= EntityName #>ListInput input); 25 | 26 | /// 27 | /// 获取<#= FunctionName #> 28 | /// 29 | TaskForEditOutput> Get<#= EntityName #>ForEdit(NullableIdDto<<#=EntityPrimaryKeyType#>> input); 30 | 31 | /// 32 | /// 创建或更新<#= FunctionName #> 33 | /// 34 | Task CreateOrUpdate<#= EntityName #>(CreateOrUpdate<#= EntityName #>Input input); 35 | 36 | /// 37 | /// 创建<#= FunctionName #> 38 | /// 39 | Task Create<#= EntityName #>(CreateOrUpdate<#= EntityName #>Input input); 40 | 41 | /// 42 | /// 更新<#= FunctionName #> 43 | /// 44 | Task Update<#= EntityName #>(CreateOrUpdate<#= EntityName #>Input input); 45 | 46 | /// 47 | /// 删除<#= FunctionName #> 48 | /// 49 | Task Delete<#= EntityName #>(EntityDto<<#=EntityPrimaryKeyType#>> input); 50 | 51 | #endregion 52 | } 53 | } -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Application/{EntityFolerName}/{Entity}AppService.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../Module.t4" #> 3 | <#@ include file="../../CSharpHelpers.t4" #> 4 | <# 5 | var entityName = ToCamelCase(EntityName); 6 | #> 7 | <#@ output extension="cs" #> 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Data.Entity; 12 | using System.Diagnostics; 13 | using System.Linq; 14 | using System.Linq.Dynamic; 15 | using System.Text; 16 | using System.Threading.Tasks; 17 | using Abp; 18 | using Abp.Application.Services.Dto; 19 | using Abp.Authorization; 20 | using Abp.AutoMapper; 21 | using Abp.Configuration; 22 | using Abp.Domain.Repositories; 23 | using Abp.Domain.Uow; 24 | using Abp.Extensions; 25 | using Abp.Linq.Extensions; 26 | using Abp.UI; 27 | using Newtonsoft.Json; 28 | using <#= EntityNamespace #>; 29 | using <#= AppName #>.<#=EntityFolerName#>.Dto; 30 | 31 | namespace <#= AppName #>.<#=EntityFolerName#> 32 | { 33 | //[AbpAuthorize(<#= EntityFolerName #>Permissions.<#= PluralEntityName #>)] 34 | public class <#= EntityName #>AppService : <#= AppName #>AppServiceBase, I<#= EntityName #>AppService 35 | { 36 | private readonly IRepository<<#= EntityName #>,<#=EntityPrimaryKeyType#>> _<#= entityName #>Repository; 37 | 38 | public <#= EntityName #>AppService( 39 | IRepository<<#= EntityName #>,<#=EntityPrimaryKeyType#>> <#= entityName #>Repository 40 | ) 41 | { 42 | _<#= entityName #>Repository = <#= entityName #>Repository; 43 | } 44 | 45 | #region <#= FunctionName #>管理 46 | 47 | /// 48 | /// 根据查询条件获取<#= FunctionName #>分页列表 49 | /// 50 | public async TaskListDto>> Get<#= EntityName #>PagedList(Get<#= EntityName #>ListInput input) 51 | { 52 | var query = _<#= entityName #>Repository.GetAll(); 53 | //TODO:根据传入的参数添加过滤条件 54 | 55 | var <#= entityName #>Count=await query.CountAsync(); 56 | 57 | var entities = await query.OrderBy(input.Sorting).PageBy(input).ToListAsync(); 58 | var dtos = entities.MapToListDto>>(); 59 | return new PagedResultDto<<#= EntityName #>ListDto>(<#= entityName #>Count, dtos); 60 | } 61 | 62 | /// 63 | /// 根据查询条件获取<#= FunctionName #>列表 64 | /// 65 | public async TaskListDto>> Get<#= EntityName #>List(Get<#= EntityName #>ListInput input) 66 | { 67 | var entities = await _<#= entityName #>Repository.GetAll().ToListAsync(); 68 | return new ListResultDto<<#= EntityName #>ListDto>(entities.MapToListDto>>()); 69 | } 70 | 71 | /// 72 | /// 获取<#= FunctionName #> 73 | /// 74 | public async TaskForEditOutput> Get<#= EntityName #>ForEdit(NullableIdDto<<#=EntityPrimaryKeyType#>> input) 75 | { 76 | <#= EntityName #>EditDto dto; 77 | if (input.Id.HasValue) 78 | { 79 | dto = (await _<#= entityName #>Repository.GetAsync(input.Id.Value)).MapTo<<#= EntityName #>EditDto>(); 80 | } 81 | else 82 | { 83 | dto = new <#= EntityName #>EditDto(); 84 | } 85 | return new Get<#= EntityName #>ForEditOutput() { <#= EntityName #> = dto }; 86 | } 87 | 88 | /// 89 | /// 创建或更新<#= FunctionName #> 90 | /// 91 | public async Task CreateOrUpdate<#= EntityName #>(CreateOrUpdate<#= EntityName #>Input input) 92 | { 93 | if (input.<#= EntityName #>.Id == null) 94 | { 95 | await Create<#= EntityName #>(input); 96 | } 97 | else 98 | { 99 | await Update<#= EntityName #>(input); 100 | } 101 | } 102 | 103 | /// 104 | /// 创建<#= FunctionName #> 105 | /// 106 | //[AbpAuthorize(<#= EntityFolerName #>Permissions.<#= PluralEntityName #>_Create<#= EntityName #>)] 107 | public virtual async Task Create<#= EntityName #>(CreateOrUpdate<#= EntityName #>Input input) 108 | { 109 | //if (await _<#= entityName #>Repository.IsExists<#= EntityName #>ByName(input.CategoryName)) 110 | //{ 111 | // throw new UserFriendlyException(L("NameIsExists")); 112 | //} 113 | var entity = await _<#= entityName #>Repository.InsertAsync(input.<#= EntityName #>.MapTo<<#= EntityName #>>()); 114 | } 115 | 116 | /// 117 | /// 更新<#= FunctionName #> 118 | /// 119 | //[AbpAuthorize(<#= EntityFolerName #>Permissions.<#= PluralEntityName #>_Edit#= EntityName #>)] 120 | public virtual async Task Update<#= EntityName #>(CreateOrUpdate<#= EntityName #>Input input) 121 | { 122 | //if (await _<#= entityName #>Repository.IsExists<#= EntityName #>ByName(input.CategoryName, input.Id)) 123 | //{ 124 | // throw new UserFriendlyException(L("NameIsExists")); 125 | //} 126 | if (input.<#= EntityName #>.Id != null) 127 | { 128 | var entity = await _<#= entityName #>Repository.GetAsync(input.<#= EntityName #>.Id.Value); 129 | await _<#= entityName #>Repository.UpdateAsync(input.<#= EntityName #>.MapTo(entity)); 130 | } 131 | } 132 | 133 | /// 134 | /// 删除<#= FunctionName #> 135 | /// 136 | //[AbpAuthorize(<#= EntityFolerName #>Permissions.<#= PluralEntityName #>_Delete<#= EntityName #>)] 137 | public async Task Delete<#= EntityName #>(EntityDto<<#=EntityPrimaryKeyType#>> input) 138 | { 139 | //TODO:删除前的逻辑判断,是否允许删除 140 | await _<#= entityName #>Repository.DeleteAsync(input.Id); 141 | } 142 | 143 | #endregion 144 | 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Common/AdminNavigationProvider.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../Web.t4" #> 3 | <#@ include file="../CSharpHelpers.t4" #> 4 | <#@ output extension="cs" #> 5 | <# 6 | var entityName = ToCamelCase(EntityName); 7 | #> 8 | 9 | /* 10 | //TODO: ★请将以下内容剪切到AdminNavigationProvider.cs 11 | .AddItem(new MenuItemDefinition( 12 | AdminPageNames.Common.<#=PluralEntityName#>, 13 | L("<#=PluralEntityName#>"), 14 | url: "Admin/<#=PluralEntityName#>", 15 | icon: "icon-globe", 16 | requiredPermissionName: AppPermissions.<#= PluralEntityName #> 17 | ) 18 | ) 19 | 20 | //TODO:★请将以下内容剪切到AdminPageNames.cs 21 | public class AdminPageNames 22 | { 23 | public static class Common 24 | { 25 | public const string <#=PluralEntityName#> = "<#=PluralEntityName#>"; 26 | 27 | } 28 | } 29 | 30 | */ 31 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Common/AppPermissions.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../Module.t4" #> 3 | <#@ include file="../CSharpHelpers.t4" #> 4 | <#@ output extension="cs" #> 5 | <# 6 | var entityName = ToCamelCase(EntityName); 7 | #> 8 | //TODO:★请将以下内容剪切到AppPermissions.cs 9 | /* 10 | // <#= FunctionName #>管理权限 11 | public const string <#= PluralEntityName #> = "<#= PluralEntityName #>"; 12 | public const string <#= PluralEntityName #>_Create = "<#= PluralEntityName #>.Create"; 13 | public const string <#= PluralEntityName #>_Edit = "<#= PluralEntityName #>.Edit"; 14 | public const string <#= PluralEntityName #>_Delete = "<#= PluralEntityName #>.Delete"; 15 | */ 16 | 17 | //TODO:★请将以下内容剪切到AppAuthorizationProvider.cs 18 | /* 19 | //<#= FunctionName #>管理 20 | var <#= entityName #> = administration.CreateChildPermission(AppPermissions.<#= PluralEntityName #>, L("<#= PluralEntityName #>")); 21 | <#= entityName #>.CreateChildPermission(AppPermissions.<#= PluralEntityName #>_Create, L("Create<#= EntityName #>")); 22 | <#= entityName #>.CreateChildPermission(AppPermissions.<#= PluralEntityName #>_Edit, L("Edit<#= EntityName #>")); 23 | <#= entityName #>.CreateChildPermission(AppPermissions.<#= PluralEntityName #>_Delete, L("Delete<#= EntityName #>")); 24 | 25 | */ 26 | 27 | //TODO:★请将以下内容剪切到语言包 28 | /* 29 | 30 | 31 | 32 | 33 | 34 | 35 | */ 36 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Core/IRepositories/I{Entity}Repository.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Abp.Domain.Repositories; 10 | using Abp.Extensions; 11 | using <#= EntityNamespace #>; 12 | 13 | namespace <#=AppName#>.IRepositories 14 | { 15 | public interface I<#= EntityName #>Repository : IRepository<<#= EntityName #>> 16 | { 17 | 18 | } 19 | } -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.EntityFramework/EntityFramework/Repositories/{Entity}Repository.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../Module.t4" #> 3 | <#@ output extension="cs" #> 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Data.Entity; 10 | using <#=AppName#>.IRepositories; 11 | using Abp.EntityFramework; 12 | using <#= EntityNamespace #>; 13 | 14 | namespace <#=AppName#>.EntityFramework.Repositories 15 | { 16 | public class <#= EntityName #>Repository : <#= AppName #>RepositoryBase<<#= EntityName #>>, I<#= EntityName #>Repository 17 | { 18 | public <#= EntityName #>Repository(IDbContextProvider<<#= AppName #>DbContext> dbContextProvider) 19 | : base(dbContextProvider) 20 | { 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Web/Areas/{Module}/Controllers/{PluralEntityName}Controller.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../../Web.t4" #> 3 | <#@ include file="../../../../CSharpHelpers.t4" #> 4 | <#@ output extension="cs" #> 5 | <# 6 | var entityName = ToCamelCase(EntityName); 7 | #> 8 | using System.Threading.Tasks; 9 | using Abp.Application.Services.Dto; 10 | using Abp.AspNetCore.Mvc.Authorization; 11 | using Microsoft.AspNetCore.Mvc; 12 | using <#=AppName#>.Address.Country; 13 | using <#=AppName#>.Authorization; 14 | using <#=AppName#>.Web.Areas.Admin.Models.<#=PluralEntityName#>; 15 | using <#= AppName #>.<#=EntityFolerName#>; 16 | namespace <#=AppName#>.Web.Areas.Admin.Controllers 17 | { 18 | //[AbpMvcAuthorize(AppPermissions.Pages_<#=PluralEntityName#>)] 19 | public class <#=PluralEntityName#>Controller : AdminControllerBase 20 | { 21 | private readonly I<#=EntityName#>AppService _<#=entityName#>AppService; 22 | 23 | public <#=PluralEntityName#>Controller(I<#=EntityName#>AppService <#=entityName#>AppService) 24 | { 25 | _<#=entityName#>AppService = <#=entityName#>AppService; 26 | } 27 | 28 | public ActionResult Index() 29 | { 30 | return View(); 31 | } 32 | 33 | //[AbpMvcAuthorize(AppPermissions.Pages_<#=PluralEntityName#>_Create, AppPermissions.Pages_<#=PluralEntityName#>_Edit)] 34 | public async Task CreateOrEditModal(int? id) 35 | { 36 | var output = await _<#=entityName#>AppService.Get<#=EntityName#>ForEdit(new NullableIdDto { Id = id }); 37 | var viewModel = new CreateOrEdit<#=EntityName#>ModalViewModel(output); 38 | 39 | return PartialView("_CreateOrEditModal", viewModel); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Web/Areas/{Module}/Models/{PluralEntityName}/CreateOrEdit{Entity}ModalViewModel.cs.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../../../Web.t4" #> 3 | <#@ output extension="cs" #> 4 | using Abp.AutoMapper; 5 | using <#=DtoNamespace#>; 6 | 7 | namespace <#=AppName#>.Web.Areas.Admin.Models.<#=PluralEntityName#> 8 | { 9 | [AutoMapFrom(typeof(Get<#=EntityName#>ForEditOutput))] 10 | public class CreateOrEdit<#=EntityName#>ModalViewModel : Get<#=EntityName#>ForEditOutput 11 | { 12 | public CreateOrEdit<#=EntityName#>ModalViewModel(Get<#=EntityName#>ForEditOutput output) 13 | { 14 | output.MapTo(this); 15 | } 16 | public bool IsEditMode 17 | { 18 | get { return <#=EntityName#>.Id.HasValue; } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Web/Areas/{Module}/Views/{PluralEntityName}/Index.cshtml.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../../../Web.t4" #> 3 | <#@ output extension="cshtml" #> 4 | @using <#=AppName#>.Authorization 5 | @using <#=AppName#>.Web.Areas.Admin.Startup 6 | @{ 7 | ViewBag.CurrentPageName = AdminPageNames.Common.<#=PluralEntityName#>; 8 | } 9 | @section Styles 10 | { 11 | 12 | 13 | 14 | 15 | 16 | 17 | } 18 | @section Scripts 19 | { 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | } 29 |
30 |
31 |
32 |
33 |

34 | @L("<#=PluralEntityName#>") @L("<#=PluralEntityName#>HeaderInfo") 35 |

36 |
37 |
38 |
39 |
40 | @if (IsGranted(AppPermissions.<#=PluralEntityName#>_Create)) 41 | { 42 | 43 | } 44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Web/Areas/{Module}/Views/{PluralEntityName}/_CreateOrEditModal.cshtml.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../../../Web.t4" #> 3 | <#@ output extension="cshtml" #> 4 | @using Abp.Extensions 5 | @using <#=AppName#>.Web.Areas.Admin.Models.Common.Modals 6 | @using <#=AppName#>.Web.Areas.Admin.Models.<#=PluralEntityName#> 7 | @model CreateOrEdit<#=EntityName#>ModalViewModel 8 | 9 | @Html.Partial("~/Areas/Admin/Views/Common/Modals/_ModalHeader.cshtml", new ModalHeaderViewModel(Model.IsEditMode ? (L("Edit<#=EntityName#>") + ": " ) : L("CreateNew<#=EntityName#>"))) 10 | 30 | @Html.Partial("~/Areas/Admin/Views/Common/Modals/_ModalFooterWithSaveAndCancel.cshtml") -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Web/wwwroot/view-resources/Areas/{Module}/Views/{PluralEntityName}/Index.js.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../../../../../Web.t4" #> 3 | <#@ include file="../../../../../../../CSharpHelpers.t4" #> 4 | <#@ output extension="js" #> 5 | <# 6 | var entityName = ToCamelCase(EntityName); 7 | var pluralEntityName = ToCamelCase(PluralEntityName); 8 | #> 9 | (function () { 10 | $(function () { 11 | 12 | var _$<#=pluralEntityName#>Table = $('#<#=PluralEntityName#>Table'); 13 | var _<#=entityName#>Service = abp.services.app.<#=entityName#>; 14 | 15 | var _permissions = { 16 | create: abp.auth.hasPermission('<#=PluralEntityName#>.Create'), 17 | edit: abp.auth.hasPermission('<#=PluralEntityName#>.Edit'), 18 | 'delete': abp.auth.hasPermission('<#=PluralEntityName#>.Delete') 19 | }; 20 | 21 | var _createOrEditModal = new app.ModalManager({ 22 | viewUrl: abp.appPath + 'Admin/<#=PluralEntityName#>/CreateOrEditModal', 23 | scriptUrl: abp.appPath + 'view-resources/Areas/Admin/Views/<#=PluralEntityName#>/_CreateOrEditModal.js', 24 | modalClass: 'CreateOrEdit<#=EntityName#>Modal' 25 | }); 26 | 27 | _$<#=pluralEntityName#>Table.jtable({ 28 | 29 | title: app.localize('<#=PluralEntityName#>'), 30 | 31 | actions: { 32 | listAction: { 33 | method: _<#=entityName#>Service.getGet<#=EntityName#>PagedList 34 | } 35 | }, 36 | 37 | fields: { 38 | id: { 39 | key: true, 40 | list: false 41 | }, 42 | actions: { 43 | title: app.localize('Actions'), 44 | width: '25%', 45 | display: function (data) { 46 | var $span = $(''); 47 | 48 | if (_permissions.edit) { 49 | $('') 50 | .appendTo($span) 51 | .click(function () { 52 | _createOrEditModal.open({ id: data.record.id }); 53 | }); 54 | } 55 | 56 | if (_permissions.delete) { 57 | $('') 58 | .appendTo($span) 59 | .click(function () { 60 | delete<#=EntityName#>(data.record); 61 | }); 62 | } 63 | 64 | return $span; 65 | } 66 | }, 67 | <# 68 | foreach (MetaColumnInfo column in DtoMetaTable.Columns) 69 | { 70 | if (!column.IsDtoVisible) continue; 71 | #> 72 | <#=ToCamelCase(column.Name)#>: { 73 | title:"<#=column.DisplayName#>" 74 | }, 75 | <# 76 | } 77 | #> 78 | } 79 | 80 | }); 81 | 82 | function delete<#=EntityName#>(<#=entityName#>) { 83 | abp.message.confirm( 84 | app.localize('<#=EntityName#>DeleteWarningMessage', <#=entityName#>.name), 85 | function (isConfirmed) { 86 | if (isConfirmed) { 87 | _<#=entityName#>Service.delete<#=EntityName#>({ 88 | id: <#=entityName#>.id 89 | }).done(function () { 90 | get<#=PluralEntityName#>(); 91 | abp.notify.success(app.localize('SuccessfullyDeleted')); 92 | }); 93 | } 94 | } 95 | ); 96 | }; 97 | 98 | $('#CreateNew<#=EntityName#>Button').click(function () { 99 | _createOrEditModal.open(); 100 | }); 101 | 102 | $('#Refresh<#=PluralEntityName#>Button').click(function (e) { 103 | e.preventDefault(); 104 | get<#=PluralEntityName#>(); 105 | }); 106 | 107 | function get<#=PluralEntityName#>() { 108 | _$<#=pluralEntityName#>Table.jtable('load', {}); 109 | } 110 | 111 | abp.event.on('app.createOrEdit<#=EntityName#>ModalSaved', function () { 112 | get<#=PluralEntityName#>(); 113 | }); 114 | 115 | get<#=PluralEntityName#>(); 116 | }); 117 | })(); -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Web/wwwroot/view-resources/Areas/{Module}/Views/{PluralEntityName}/_CreateOrEditModal.js.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../../../../../Web.t4" #> 3 | <#@ include file="../../../../../../../CSharpHelpers.t4" #> 4 | <#@ output extension="js" #> 5 | <# 6 | var entityName = ToCamelCase(EntityName); 7 | #> 8 | (function () { 9 | app.modals.CreateOrEdit<#=EntityName#>Modal = function () { 10 | 11 | var _modalManager; 12 | var _<#=entityName#>Service = abp.services.app.<#=entityName#>; 13 | var _$<#=entityName#>InformationForm = null; 14 | 15 | this.init = function (modalManager) { 16 | _modalManager = modalManager; 17 | 18 | 19 | _$<#=entityName#>InformationForm = _modalManager.getModal().find('form[name=<#=EntityName#>InformationsForm]'); 20 | _$<#=entityName#>InformationForm.validate({ ignore: "" }); 21 | }; 22 | 23 | this.save = function () { 24 | if (!_$<#=entityName#>InformationForm.valid()) { 25 | return; 26 | } 27 | 28 | var <#=entityName#> = _$<#=entityName#>InformationForm.serializeFormToObject(); 29 | 30 | _modalManager.setBusy(true); 31 | _<#=entityName#>Service.createOrUpdate<#=EntityName#>({ 32 | <#=entityName#>: <#=entityName#> 33 | }).done(function () { 34 | abp.notify.info(app.localize('SavedSuccessfully')); 35 | _modalManager.close(); 36 | abp.event.trigger('app.createOrEdit<#=EntityName#>ModalSaved'); 37 | }).always(function () { 38 | _modalManager.setBusy(false); 39 | }); 40 | }; 41 | }; 42 | })(); -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/Templates/ABPScaffolder/{AppName}.Web/wwwroot/view-resources/Areas/{Module}/Views/{PluralEntityName}/index.less.t4: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" HostSpecific="True" Debug="False" #> 2 | <#@ include file="../../../../../../../Web.t4" #> 3 | <#@ output extension="less" #> 4 | @tableWidth: 320px; 5 | 6 | #<#=PluralEntityName#>Table { 7 | .jtable-main-container { 8 | .jtable-title { 9 | min-width: @tableWidth; 10 | } 11 | 12 | .jtable { 13 | min-width: @tableWidth; 14 | } 15 | 16 | .jtable-bottom-panel { 17 | min-width: @tableWidth; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/UI/BindBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Input; 3 | 4 | namespace Poepon.AbpCodeGenerator.Core.UI 5 | { 6 | internal class BindBehavior 7 | { 8 | #region ForceBindOnLostFocusProperty 9 | 10 | public static readonly DependencyProperty ForceBindOnLostFocusProperty = 11 | DependencyProperty.RegisterAttached( 12 | "ForceBindOnLostFocus", 13 | typeof(DependencyProperty), 14 | typeof(BindBehavior), 15 | new UIPropertyMetadata(null, ForceBindOnLostFocusOnChanged)); 16 | 17 | public static DependencyProperty GetForceBindOnLostFocus(DependencyObject obj) 18 | { 19 | return (DependencyProperty)obj.GetValue(ForceBindOnLostFocusProperty); 20 | } 21 | 22 | public static void SetForceBindOnLostFocus(DependencyObject obj, DependencyProperty value) 23 | { 24 | obj.SetValue(ForceBindOnLostFocusProperty, value); 25 | } 26 | 27 | private static void ForceBindOnLostFocusOnChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 28 | { 29 | var targetElement = obj as FrameworkElement; 30 | if (targetElement != null && e.NewValue != null) 31 | { 32 | targetElement.LostKeyboardFocus += ForceBindOnLostFocus_OnLostKeyboardFocus; 33 | } 34 | else 35 | { 36 | targetElement.LostKeyboardFocus -= ForceBindOnLostFocus_OnLostKeyboardFocus; 37 | } 38 | } 39 | 40 | private static void ForceBindOnLostFocus_OnLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 41 | { 42 | if (e.OldFocus.IsKeyboardFocusWithin) 43 | { 44 | // Just bail out if we're still ultimately in the focus of the old element. 45 | // This is the case when clicking in a ComboBox that is IsEditable=true 46 | // as the new focus is the TextBox that the ComboBox creates as a child of itself. 47 | return; 48 | } 49 | 50 | var targetElement = (FrameworkElement)e.Source; 51 | var binding = targetElement.GetBindingExpression(GetForceBindOnLostFocus(targetElement)); 52 | 53 | if (targetElement != null && binding != null) 54 | { 55 | binding.UpdateSource(); 56 | } 57 | } 58 | 59 | #endregion 60 | 61 | #region ForceBindOnEnterProperty 62 | 63 | public static readonly DependencyProperty ForceBindOnEnterProperty = 64 | DependencyProperty.RegisterAttached( 65 | "ForceBindOnEnter", 66 | typeof(DependencyProperty), 67 | typeof(BindBehavior), 68 | new UIPropertyMetadata(null, ForceBindOnEnterPropertyChanged)); 69 | 70 | public static DependencyProperty GetForceBindOnEnter(DependencyObject obj) 71 | { 72 | return (DependencyProperty)obj.GetValue(ForceBindOnEnterProperty); 73 | } 74 | 75 | public static void SetForceBindOnEnter(DependencyObject obj, DependencyProperty value) 76 | { 77 | obj.SetValue(ForceBindOnEnterProperty, value); 78 | } 79 | 80 | private static void ForceBindOnEnterPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 81 | { 82 | var targetElement = obj as FrameworkElement; 83 | if (obj != null && e.NewValue != null) 84 | { 85 | targetElement.PreviewKeyDown += ForceBindOnEnterProperty_OnPreviewKeyDown; 86 | } 87 | else 88 | { 89 | targetElement.PreviewKeyDown -= ForceBindOnEnterProperty_OnPreviewKeyDown; 90 | } 91 | } 92 | 93 | private static void ForceBindOnEnterProperty_OnPreviewKeyDown(object sender, KeyEventArgs e) 94 | { 95 | if (e.Key == Key.Enter) 96 | { 97 | var targetElement = (FrameworkElement)e.Source; 98 | var binding = targetElement.GetBindingExpression(GetForceBindOnEnter(targetElement)); 99 | 100 | if (targetElement != null && binding != null) 101 | { 102 | binding.UpdateSource(); 103 | } 104 | } 105 | } 106 | 107 | #endregion 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/UI/DelegateCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Windows.Input; 4 | 5 | namespace Poepon.AbpCodeGenerator.Core.UI 6 | { 7 | public class DelegateCommand : ICommand 8 | { 9 | readonly Action _execute; 10 | readonly Func _canExecute; 11 | 12 | public DelegateCommand(Action execute) 13 | : this(execute, null) 14 | { 15 | 16 | } 17 | 18 | public DelegateCommand(Action execute, Func canExecute) 19 | { 20 | if (execute == null) 21 | throw new ArgumentNullException("execute"); 22 | 23 | _execute = execute; 24 | _canExecute = canExecute ?? (_ => true); 25 | } 26 | 27 | [DebuggerStepThrough] 28 | public bool CanExecute(object parameter) 29 | { 30 | return _canExecute(parameter); 31 | } 32 | 33 | public event EventHandler CanExecuteChanged 34 | { 35 | add { CommandManager.RequerySuggested += value; } 36 | remove { CommandManager.RequerySuggested -= value; } 37 | } 38 | 39 | public void Execute(object parameter) 40 | { 41 | _execute(parameter); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/UI/DtoClassMemberSetting.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 16 | 28 | 40 | 44 | 48 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/UI/DtoClassMemberSetting.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace Poepon.AbpCodeGenerator.Core.UI 17 | { 18 | /// 19 | /// Interaction logic for ResultListSetting.xaml 20 | /// 21 | public partial class DtoClassMemberSetting : UserControl 22 | { 23 | public DtoClassMemberSetting() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/UI/FocusBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace Poepon.AbpCodeGenerator.Core.UI 6 | { 7 | internal class FocusBehavior 8 | { 9 | public static readonly DependencyProperty FocusOnFirstElementProperty = 10 | DependencyProperty.RegisterAttached( 11 | "FocusOnFirstElement", 12 | typeof(bool), 13 | typeof(FocusBehavior), 14 | new PropertyMetadata(false, OnFocusOnFirstElementPropertyChanged)); 15 | 16 | public static bool GetFocusOnFirstElement(Control control) 17 | { 18 | return (bool)control.GetValue(FocusOnFirstElementProperty); 19 | } 20 | 21 | public static void SetFocusOnFirstElement(Control control, bool value) 22 | { 23 | control.SetValue(FocusOnFirstElementProperty, value); 24 | } 25 | 26 | static void OnFocusOnFirstElementPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 27 | { 28 | var control = obj as Control; 29 | if (control == null || !(args.NewValue is bool)) 30 | { 31 | return; 32 | } 33 | 34 | if ((bool)args.NewValue) 35 | { 36 | control.Loaded += (sender, e) => control.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Poepon.AbpCodeGenerator.Core/UI/GeneratorAreaDialog.xaml: -------------------------------------------------------------------------------- 1 |  14 | 15 | 19 | 31 | 42 | 46 | 50 | 53 | 54 | 55 | 56 | 57 | 58 | 72 | 74 |