diff --git a/README.md b/README.md index 9456e27e..60961fb9 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,65 @@ -**WebFirst 代码生成器** - -- 在线生成entity、xml、dao、service、html、js、sql代码,减少70%以上的开发任务 -- 可以在线创建数据库和导出文档 -- 可在线建类并且生成表 -- 支持方案保存,模版管理 -- 超级流畅的性能 -
- - -**如何交流、反馈、参与贡献?** -- Github: https://github.com/donet5/WebFirst -- OSC Gitee:https://gitee.com/sunkaixuan/web-first -- [果糖官网] https://www.donet5.com/ -- [使用文档] https://www.donet5.com/Doc/11 -- [可执行exe文件下载] https://www.donet5.com/Doc/11/2388 -- 官方QQ群:958343000 -- 技术讨论、二次开发等咨询、问题和建议,请移步到果糖网,我会在第一时间进行解答和回复 -- 如需关注项目最新动态,请Watch、Star项目,同时也是对项目最好的支持 -- 微信扫码加好友【果糖网】,与作者互动

-![输入图片说明](https://www.donet5.com/_theme/img/addWX.jpg "加微信") - - **本地部署代码生成器** -- 通过git下载源码 -- F5直接运行项目 -- 安装VS2019 c#,则可启动项目 -- 项目访问路径:默认 - -**代码生成器演示效果图:** -![输入图片说明](https://www.donet5.com/_theme/ueditor/utf8-net/net/upload/image/20211001/6376869443519224327257971.png "用例") +## 框架描述 +WebFirst 是果糖大数据团队开发的新一代 高性能 代码生成器&数据库设计工具,由.net core + sqlsugar 开发 导入1000个表只要1-2秒,用法简单,功能强大,支持多种数据库 +### 图片预览 + +![输入图片说明](https://www.donet5.com//_theme/ueditor/utf8-net/net/upload/image/20211009/6376941449795119979562201.png "用例") + +### 功能预览 + +1、 建库、CodeFirst方式在线建表,没用到CodeFirst的用户可以用工具轻松体验,支持公共字段 + +2、导出EXCEL文档,把每个表的数据导出来 + +3、模版管理 可以自个添加修改模版,使用的是Razor模版引擎对C#程序员更加友好 + +4、方案管理,可以创建自已的生成方案,修改方案 + +5、支持扩展模版属性,支持生成更加丰富的前端代码 + +6、支持生成解决方案 + +7、支持生成附加文件,支持文件后缀 + +8、支持视图 + +9、支持自定义数据类型 + +10、支持多种数据库 MYSQL PGSQL SQLITE SQLSERVE ORCLE 达梦 + +### 功能特色 +1、生成器与你具体的项目解耦,可以独立管理多个解决方案 + +2、支持一键生成多个解决方案 + +3、支持EXE方式和Web方式部署 + +## 使用场景 + +1、提高工作效率 + +我们都知道一个CRUD其实如果有代码生成器的话只需要几分钟就可以把完整的功能做完,如果用手去写那么可能就要花掉一整天的时间,多出来的这些时间学学技术多好 + +2、大量重复有共性的功能 + +使用代码生成器最重要的就是减少大量重复的工作,比如我们有 数据库model 有表单model 有Grid绑定的 model 光写这些MODEL就很头痛,要写各种特性 + +## 使用教程 +### 配置实体 +1、通过数据库导入实体: 菜单【配置实体(表建类模式)】 + +2、在线建实体 : 菜单【配置实体(类建表模式)】 + +3、通过SQL建实体: 菜单【配置实体(视图模式)】 +### 一键生成 +配置实体后就可以使用自带的一键生成功能来生成用例代码,通过自带方案和模版的配置可以快速了解框架 +### 方案管理 +一键生成可以生成多个方案,方案 包含: 模版、路径、文件名、文件后缀 等 可以理解为某个模版的生成配置 +### 模版管理 +模版是方案的一个重要参数,什么样的模版 生成什么样的文件内容,比如 实体类就编写实体类模版 ,业务就编写业务模版 + + +## 下载软件 +[WebFirst最新版本下载](https://www.donet5.com/Doc/11/2388) + +## QQ群交流 +QQ交流群: 958343000 diff --git a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController.cs b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController.cs index 50fcb0b6..5428dd48 100644 --- a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController.cs +++ b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController.cs @@ -321,14 +321,17 @@ public ActionResult> CreateFileByProjectId([FromForm] ProjectVie var tableList = CodeTableDb.GetList(it => tableids.Contains(it.Id)); int dbId = tableList.First().DbId; var connection = base.GetTryDb(dbId); - List genList = GetGenList(tableList, CodeTypeDb.GetList(), connection.CurrentConnectionConfig.DbType); + List genList = GetGenList(tableList, CodeTypeDb.GetList(),connection, connection.CurrentConnectionConfig.DbType); string key = TemplateHelper.EntityKey + template.GetHashCode(); foreach (var item in genList) { item.name_space = GetNameSpace(project.FileModel, item.name_space); var html = TemplateHelper.GetTemplateValue(key, template, item); var fileName = GetFileName(project, item); - FileSugar.CreateFileReplace(fileName, html, Encoding.UTF8); + if (fileName.Last() != '.') + { + FileSugar.CreateFileReplace(fileName, html, Encoding.UTF8); + } } OpenPath(disOpen, project); ProjectController_Common.CreateProject(project.Id, model.DbId.Value); @@ -376,7 +379,7 @@ public ActionResult> CreateTables([FromForm] string model, [From var list = Newtonsoft.Json.JsonConvert.DeserializeObject>(model); var oldList = CodeTableDb.AsQueryable().In(list.Select(it => it.Id).ToList()).ToList(); base.Check(oldList.Any(it => it.IsLock), string.Join(",", oldList.Where(it => it.IsLock).Select(it => it.ClassName)) + "是锁表状态禁止建表"); - List genList = GetGenList(oldList, CodeTypeDb.GetList(), tableDb.CurrentConnectionConfig.DbType); + List genList = GetGenList(oldList, CodeTypeDb.GetList(),tableDb, tableDb.CurrentConnectionConfig.DbType); foreach (var item in genList) { item.PropertyGens = item.PropertyGens.Where(it => it.IsIgnore == false).ToList(); @@ -451,7 +454,7 @@ public ActionResult> GetTableDiff([FromForm] string model, [Fr var list = Newtonsoft.Json.JsonConvert.DeserializeObject>(model); var oldList = CodeTableDb.AsQueryable().In(list.Select(it => it.Id).ToList()).ToList(); base.Check(oldList.Any(it => it.IsLock), string.Join(",", oldList.Where(it => it.IsLock).Select(it => it.ClassName)) + "是锁表状态禁止建表"); - List genList = GetGenList(oldList, CodeTypeDb.GetList(), tableDb.CurrentConnectionConfig.DbType); + List genList = GetGenList(oldList, CodeTypeDb.GetList(),tableDb, tableDb.CurrentConnectionConfig.DbType); foreach (var item in genList) { item.PropertyGens = item.PropertyGens.Where(it => it.IsIgnore == false).ToList(); @@ -713,7 +716,7 @@ public ActionResult> Copy([FromForm] ProjectViewModel2 model) var tableList = CodeTableDb.GetList(it => tableids.Contains(it.Id)); int dbId = tableList.First().DbId; var connection = base.GetTryDb(dbId); - List genList = GetGenList(tableList, CodeTypeDb.GetList(), connection.CurrentConnectionConfig.DbType); + List genList = GetGenList(tableList, CodeTypeDb.GetList(),connection, connection.CurrentConnectionConfig.DbType); string key = TemplateHelper.EntityKey + template.GetHashCode(); foreach (var item in genList.Take(1)) { diff --git a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_CreateFile.cs b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_CreateFile.cs index 896999eb..2cd74f7a 100644 --- a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_CreateFile.cs +++ b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_CreateFile.cs @@ -1,5 +1,6 @@ using AutoMapper; using Microsoft.AspNetCore.Mvc; +using Npgsql.TypeHandlers.DateTimeHandlers; using SqlSugar; using System; using System.Collections.Generic; @@ -52,7 +53,7 @@ private static void OpenPath(string path) } } - private List GetGenList(List tableList, List types,SqlSugar.DbType databasedbType) + private List GetGenList(List tableList, List types, SqlSugarClient db, SqlSugar.DbType databasedbType) { List result = new List(); var mapping = Db.Queryable().ToList(); @@ -67,6 +68,11 @@ private List GetGenList(List tableList, List t } foreach (var item in tableList) { + var tableColumns = new List { }; + if (db.DbMaintenance.IsAnyTable(item.TableName,false)) + { + tableColumns=db.DbMaintenance.GetColumnInfosByTableName(item.TableName, false); + } EntitiesGen gen = new EntitiesGen() { ClassName = item.ClassName, @@ -102,6 +108,11 @@ private List GetGenList(List tableList, List t else { var dbType = GetTypeInfoByDatabaseType(codeType.DbType, databasedbType); + var dbColumnInfo = tableColumns.FirstOrDefault(it => it.DbColumnName.ToLower() == column.DbColumnName.ToLower()); + if (!string.IsNullOrEmpty(dbColumnInfo?.OracleDataType)) + { + dbColumnInfo.DataType = dbColumnInfo.OracleDataType; + } PropertyGen proGen = new PropertyGen() { DbColumnName = column.DbColumnName, @@ -113,6 +124,9 @@ private List GetGenList(List tableList, List t IsNullable = column.Required == false, DbType = dbType.Name, Length = dbType.Length, + Db_Length = dbColumnInfo?.Length, + Db_DecimalDigits = dbColumnInfo?.DecimalDigits, + Db_DateType=dbColumnInfo?.DataType, DecimalDigits = dbType.DecimalDigits, IsSpecialType= IsSpecialType(column), CodeType= column.CodeType, @@ -160,6 +174,7 @@ private DbTypeInfo GetTypeInfoByDatabaseType(DbTypeInfo[] dbType, DbType databas break; case DbType.SqlServer: mstypes= SqlSugar.SqlServerDbBind.MappingTypesConst.Select(it => it.Key.ToLower()).ToList(); + mstypes.Add("xml"); break; case DbType.Sqlite: mstypes = SqlSugar.SqliteDbBind.MappingTypesConst.Select(it => it.Key.ToLower()).ToList(); @@ -220,7 +235,18 @@ private string GetFileName(Project project, EntitiesGen item) } else if (!string.IsNullOrEmpty(project.NameFormat)) { - name = string.Format(project.NameFormat, item.ClassName); + if (project.NameFormat.Contains("{TableName}")) + { + name = project.NameFormat.Replace("{TableName}",item.TableName); + } + else if (project.NameFormat.Contains("{ClassName}")) + { + name = project.NameFormat.Replace("{ClassName}", item.ClassName); + } + else + { + name = string.Format(project.NameFormat, item.ClassName); + } } return FileSugar.MergeUrl(project.Path, name + p + project.FileSuffix); } diff --git a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_Export.cs b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_Export.cs index cdf78bd5..31a377ca 100644 --- a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_Export.cs +++ b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_Export.cs @@ -17,7 +17,7 @@ private DataTable [] Export(string model, SqlSugarClient tableDb) { var list = Newtonsoft.Json.JsonConvert.DeserializeObject>(model); var oldList = CodeTableDb.AsQueryable().In(list.Select(it => it.Id).ToList()).ToList(); - List genList = GetGenList(oldList, CodeTypeDb.GetList(), tableDb.CurrentConnectionConfig.DbType); + List genList = GetGenList(oldList, CodeTypeDb.GetList(),tableDb, tableDb.CurrentConnectionConfig.DbType); List datatables = new List(); foreach (var item in genList) { diff --git a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_SaveCodetableImport.cs b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_SaveCodetableImport.cs index abe5e61d..f84aaac0 100644 --- a/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_SaveCodetableImport.cs +++ b/SoEasyPlatform/Apis/CodeTableApp/CodeTableController_SaveCodetableImport.cs @@ -17,22 +17,27 @@ public partial class CodeTableController : BaseController private SortTypeInfo GetEntityType(List types, DbColumnInfo columnInfo, CodeTableController codeTableController,DbType dbtype) { var typeInfo = types.FirstOrDefault(y => y.DbType.Any(it => it.Name.Equals(columnInfo.DataType, StringComparison.OrdinalIgnoreCase))); - if(typeInfo == null && columnInfo.DataType == "Double") + if (typeInfo == null && (columnInfo.DataType + "").ToLower() == "double") { var type = types.First(it => it.Name == "decimal_18_4"); return new SortTypeInfo() { CodeType = type, DbTypeInfo = type.DbType[0] }; } + else if (typeInfo == null && columnInfo.DataType == "int unsigned") + { + var type = types.First(it => it.Name == "int"); + return new SortTypeInfo() { CodeType = type, DbTypeInfo = type.DbType[0] }; + } else if (typeInfo == null) { var type = types.First(it => it.Name == "string100"); return new SortTypeInfo() { CodeType = type, DbTypeInfo = type.DbType[0] }; } - else if (columnInfo.DataType == "json") + else if (columnInfo.DataType == "json") { var type = types.First(it => it.Name.ToLower() == "string2000"); return new SortTypeInfo() { CodeType = type, DbTypeInfo = type.DbType[0] }; } - else if (columnInfo.DataType == "timestamp"&&dbtype!=DbType.SqlServer) + else if (columnInfo.DataType == "timestamp" && dbtype != DbType.SqlServer) { var type = types.First(it => it.Name.ToLower() == "datetime"); return new SortTypeInfo() { CodeType = type, DbTypeInfo = type.DbType[0] }; diff --git a/SoEasyPlatform/Apis/ProjectApp/ProjectController_Common.cs b/SoEasyPlatform/Apis/ProjectApp/ProjectController_Common.cs index f9ab431f..7a16fdf4 100644 --- a/SoEasyPlatform/Apis/ProjectApp/ProjectController_Common.cs +++ b/SoEasyPlatform/Apis/ProjectApp/ProjectController_Common.cs @@ -42,6 +42,12 @@ public static void CreateProject(Project project,int dbid=0) var db = DbScoped.Sugar.Queryable().InSingle(dbid); fileInfo.Content = fileInfo.Content.Replace("[请设置DbType]","SqlSugar.DbType."+db.DbType+"").Replace("[请设置ConStr]", "@@\""+db.Connection.Replace("@","@@")+"\""); } + else if (dbid > 0 && fileInfo.Content.Contains("[ConStr]")) + { + var db = DbScoped.Sugar.Queryable().InSingle(dbid); + fileInfo.Content = fileInfo.Content.Replace("[DbType]", db.DbType+"" ) + .Replace("[ConStr]", db.Connection.Replace("@", "@@") ); + } var context = fileInfo.Content; if (!string.IsNullOrEmpty(project.Reference)) { @@ -63,7 +69,7 @@ public static void CreateProject(Project project,int dbid=0) } var html = TemplateHelper.GetTemplateValue(context, context, jsonItem); var name = (jsonItem as IDictionary)["name"]; - var fileName = FileSugar.MergeUrl(project.Path, name + "." + fileInfo.Suffix.TrimStart('.')); + var fileName = FileSugar.MergeUrl(project.Path,fileInfo.Directory, name + "." + fileInfo.Suffix.TrimStart('.')); if (!FileSugar.IsExistFile(fileName)) FileSugar.CreateFile(fileName, html); if (fileName.EndsWith(".csproj")) diff --git a/SoEasyPlatform/Apis/ProjectGroupApp/ProjectGroupController.cs b/SoEasyPlatform/Apis/ProjectGroupApp/ProjectGroupController.cs index f9832ed5..5883ba8d 100644 --- a/SoEasyPlatform/Apis/ProjectGroupApp/ProjectGroupController.cs +++ b/SoEasyPlatform/Apis/ProjectGroupApp/ProjectGroupController.cs @@ -127,6 +127,62 @@ public ActionResult> BuilderProjects([FromForm] string model, [F result.IsSuccess = true; return result; } + /// + /// 执行一键生成通过下载 + /// + /// + [HttpPost] + [Route("BuilderProjectsByHttp")] + public ApiResult BuilderProjectsByHttp([FromForm] string model, [FromForm] int pgid, [FromForm] int dbid) + { + var result = new ApiResult(); + if (!string.IsNullOrEmpty(model)) + { + var group = Db.Queryable().InSingle(pgid); + var projectids = group.ProjectIds; + var list = Db.Queryable().In(projectids).OrderBy(it => it.ModelId).ToList(); + result.Data = group.SolutionPath; + try + { + Db.BeginTran(); + foreach (var item in list) + { + var name = System.IO.Path.GetFileName(item.Path); + item.Path = System.IO.Path.Combine(group.SolutionPath, name); + + + + Db.Updateable(item).ExecuteCommand(); + new CodeTableController(null).CreateFileByProjectId(new ProjectViewModel2 + { + Tables = model, + ProjectId = item.Id, + DbId = dbid, + ModelId = item.ModelId + }, false); + } + + if (!System.IO.Directory.Exists(System.IO.Path.Combine("wwwroot", "temp"))) + { + System.IO.Directory.CreateDirectory(System.IO.Path.Combine("wwwroot", "temp"));//不存在就创建文件夹 + } + var zipName = $"{DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss")}.zip"; + var zipPath = System.IO.Path.Combine("wwwroot", "temp", zipName); + ZipHelper.ZipFileDirectory(result.Data, zipPath); + result.Data = System.IO.Path.Combine("temp", zipName).Replace("\\","/"); + + Db.CommitTran(); + } + catch (Exception ex) + { + Db.RollbackTran(); + throw ex; + } + } + result.IsSuccess = true; + + return result; + } /// /// 删除解决方案 diff --git a/SoEasyPlatform/Code/AppStart/InitTable.cs b/SoEasyPlatform/Code/AppStart/InitTable.cs index df507a3c..f37beded 100644 --- a/SoEasyPlatform/Code/AppStart/InitTable.cs +++ b/SoEasyPlatform/Code/AppStart/InitTable.cs @@ -6,7 +6,7 @@ using SqlSugar; namespace SoEasyPlatform { - public class InitTable + public partial class InitTable { /// /// 默认实体ID @@ -59,6 +59,8 @@ public void Start() InitTagProperty(db); InitOther(db); + + InitProjects(db); } private void InitOther(SqlSugarClient db) @@ -87,11 +89,11 @@ private void InitProject(SqlSugarClient db) { FileSuffix = ".cs", TemplateId1 = _entitytempId + "", - FileModel = "[{ \"name\":\"" + _defaultNamespace + ".Entities\",\"nuget\":[{ \"name\":\"SqlSugarCore\",\"version\":\"5.0.7.8\" }]}]", + FileModel = "[{ \"name\":\"" + _defaultNamespace + ".Entities\",\"nuget\":[{ \"name\":\"SqlSugarCore\",\"version\":\"5.1.4.108\" }]}]", FileInfo = _net5lib + "", NameFormat = "DbModels\\{0}", ProjentName = "[简单三层]_方案_实体_Sugar", - Path = @"c:\" + _defaultNamespace + @"\Entites", + Path =FileSugar.MergeUrl( @"c:\" + _defaultNamespace + @"\Entites"), IsDeleted = false, IsInit = true, ModelId = 1 @@ -101,10 +103,10 @@ private void InitProject(SqlSugarClient db) FileSuffix = ".cs", NameFormat = "Services\\{0}Manager", TemplateId1 = _biztempId + "", - FileModel = "[{ \"name\":\""+_defaultNamespace+ ".Services\",\"nuget\":[{ \"name\":\"SqlSugarCore\",\"version\":\"5.0.7.8\" }]},{\"name\":\"Repository\", \"name_space\":\"" + _defaultNamespace+ ".Services\" }]", + FileModel = "[{ \"name\":\""+_defaultNamespace+ ".Services\",\"nuget\":[{ \"name\":\"SqlSugarCore\",\"version\":\"5.1.4.108\" }]},{\"name\":\"Repository\", \"name_space\":\"" + _defaultNamespace+ ".Services\" }]", FileInfo = _net5lib + ","+_dbcontext, ProjentName = "[简单三层]_方案_业务_Sugar", - Path = @"c:\" + _defaultNamespace + @"\Services", + Path = FileSugar.MergeUrl(@"c:\" + _defaultNamespace + @"\Services"), IsDeleted = false, IsInit = true, ModelId = 2, @@ -114,11 +116,11 @@ private void InitProject(SqlSugarClient db) { FileSuffix = ".cs", TemplateId1 = _webtempId + "", - FileModel = "[{ \"name\":\"命名空间\",\"nuget\":[{ \"name\":\"SqlSugarCore\",\"version\":\"5.0.7.8\" },{ \"name\":\"Microsoft.AspNetCore.Mvc.NewtonsoftJson\",\"version\":\"5.0.10\" },{ \"name\":\"Swashbuckle.AspNetCore\",\"version\":\"5.6.3\" }]},{\"name\":\"Startup\", \"name_space\":\"命名空间\" },{\"name\":\"Program\", \"name_space\":\"命名空间\" },{\"name\":\"appsettings\", \"name_space\":\"命名空间\"}]".Replace("命名空间",$"{_defaultNamespace}.Api"), + FileModel = "[{ \"name\":\"命名空间\",\"nuget\":[{ \"name\":\"SqlSugarCore\",\"version\":\"5.1.4.108\" },{ \"name\":\"Microsoft.AspNetCore.Mvc.NewtonsoftJson\",\"version\":\"5.0.10\" },{ \"name\":\"Swashbuckle.AspNetCore\",\"version\":\"5.6.3\" }]},{\"name\":\"Startup\", \"name_space\":\"命名空间\" },{\"name\":\"Program\", \"name_space\":\"命名空间\" },{\"name\":\"appsettings\", \"name_space\":\"命名空间\"}]".Replace("命名空间",$"{_defaultNamespace}.Api"), FileInfo =string.Join(",",_WebFiles), ProjentName = "[简单三层]_方案_前端_Sugar", NameFormat = "Controllers\\{0}Controller", - Path = @"c:\" + _defaultNamespace + @"\Api", + Path =FileSugar.MergeUrl( @"c:\" + _defaultNamespace + @"\Api"), IsDeleted = false, IsInit = true, ModelId = 3, @@ -132,7 +134,7 @@ private void InitProject(SqlSugarClient db) { Name = ".Net5 SqlSugar+仓储", ProjectIds = new int[] { pid, pid2, pid3 }, - SolutionPath = "c:\\WebFirst\\Demo01", + SolutionPath =FileSugar.MergeUrl( "c:\\WebFirst\\Demo01"), ProjectNames=String.Join(",", db.Queryable().In(pid, pid2, pid3).Select(it=>it.ProjentName).ToArray()) }).ExecuteReturnIdentity(); } diff --git a/SoEasyPlatform/Code/AppStart/Services.cs b/SoEasyPlatform/Code/AppStart/Services.cs index 97900b1a..90e45e4a 100644 --- a/SoEasyPlatform/Code/AppStart/Services.cs +++ b/SoEasyPlatform/Code/AppStart/Services.cs @@ -1,13 +1,8 @@ -using AutoMapper; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -namespace SoEasyPlatform +namespace SoEasyPlatform { public class Services { @@ -18,8 +13,7 @@ public static void AddServices(IServiceCollection services) services.AddAutoMapper(typeof(SoEasyPlatform.MapperProfiles).Assembly); #if DEBUG //启用动态编译 - services.AddControllersWithViews() - .AddRazorRuntimeCompilation(); + services.AddControllersWithViews().AddRazorRuntimeCompilation(); #endif services.AddControllersWithViews().AddNewtonsoftJson(opt => { diff --git a/SoEasyPlatform/Code/Util/FileHelper.cs b/SoEasyPlatform/Code/Util/FileHelper.cs index 0e5da645..f1edf0af 100644 --- a/SoEasyPlatform/Code/Util/FileHelper.cs +++ b/SoEasyPlatform/Code/Util/FileHelper.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -933,8 +934,13 @@ public static string MergeUrl(params string[] urls) } else if (urls.Length == 1) { + urls = urls.Where(it => it != null).ToArray(); return urls[0]; } + else + { + urls = urls.Where(it => it != null).ToArray(); + } StringBuilder reval = new StringBuilder(); int i = 0; char slash = '\\'; @@ -959,8 +965,43 @@ public static string MergeUrl(params string[] urls) reval.Append(itUrl); itUrl = null; } - return reval.ToString(); - } + return GetRuntimeDirectory(reval.ToString()); + } + #endregion + #region 路径处理 + public static string GetRuntimeDirectory(string path) + { + //ForLinux + if (IsLinuxRunTime()) + return GetLinuxDirectory(path); + //ForWindows + if (IsWindowRunTime()) + return GetWindowDirectory(path); + return path; + } + + //OSPlatform.Windows监测运行环境 + public static bool IsWindowRunTime() + { + return System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + } + + //OSPlatform.Linux运行环境 + public static bool IsLinuxRunTime() + { + return System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + } + + public static string GetLinuxDirectory(string path) + { + string pathTemp = Path.Combine(path); + return pathTemp.Replace("\\", "/"); + } + public static string GetWindowDirectory(string path) + { + string pathTemp = Path.Combine(path); + return pathTemp.Replace("/", "\\"); + } #endregion } } diff --git a/SoEasyPlatform/Code/Util/PubMehtod.cs b/SoEasyPlatform/Code/Util/PubMehtod.cs index 5186dba2..53ec37da 100644 --- a/SoEasyPlatform/Code/Util/PubMehtod.cs +++ b/SoEasyPlatform/Code/Util/PubMehtod.cs @@ -32,7 +32,14 @@ private static string GetFirstUpper(string dbColumnName,bool islower=false) } else { - return dbColumnName.Substring(0, 1).ToUpper() + dbColumnName.Substring(1); + if (dbColumnName.ToUpper() == dbColumnName) + { + return dbColumnName.Substring(0, 1).ToUpper() + dbColumnName.Substring(1).ToLower(); + } + else + { + return dbColumnName.Substring(0, 1).ToUpper() + dbColumnName.Substring(1); + } } } } diff --git a/SoEasyPlatform/Code/Util/SyntaxTreeHelper.cs b/SoEasyPlatform/Code/Util/SyntaxTreeHelper.cs index a4300141..f6438383 100644 --- a/SoEasyPlatform/Code/Util/SyntaxTreeHelper.cs +++ b/SoEasyPlatform/Code/Util/SyntaxTreeHelper.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Reflection; using System.Runtime.Loader; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace SoEasyPlatform @@ -15,6 +16,11 @@ public class SyntaxTreeHelper { public static Type GetModelTypeByClass(string classString, string typeName) { + var typeFirstChar = typeName.FirstOrDefault() + ""; + if (Regex.IsMatch(typeFirstChar,@"^\d$")) + { + throw new Exception("类的首字母不能是数字"); + } //Write("Parsing the code into the SyntaxTree"); SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(classString); diff --git a/SoEasyPlatform/Code/Util/ZipHelper.cs b/SoEasyPlatform/Code/Util/ZipHelper.cs new file mode 100644 index 00000000..9947584c --- /dev/null +++ b/SoEasyPlatform/Code/Util/ZipHelper.cs @@ -0,0 +1,397 @@ +/*** +* Title:"基础工具" 项目 +* Title:"基础工具" 项目 +* 主题:压缩包帮助类 +* Description: +* 功能: +* 1、压缩单个文件 +* 2、压缩多个文件 +* 3、压缩多层目录 +* 4、递归遍历目录 +* 5、解压缩一个 zip 文件 +* 6、获取压缩文件中指定类型的文件 +* 7、获取压缩文件中的所有文件 +* Date:2021 +* Version:0.1版本 +* Author:Coffee +* Modify Recoder: +*/ + +using ICSharpCode.SharpZipLib.Zip; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace SoEasyPlatform +{ + public class ZipHelper + { + /// + /// 压缩单个文件 + /// + /// 要压缩的文件 + /// 压缩后的文件 + /// 压缩等级 + /// 每次写入大小 + public static void ZipFile(string fileToZip, string zipedFile, int compressionLevel, int blockSize) + { + //如果文件没有找到,则报错 + if (!File.Exists(fileToZip)) + { + throw new FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!"); + } + + using (FileStream ZipFile = File.Create(zipedFile)) + { + using (ZipOutputStream ZipStream = new ZipOutputStream(ZipFile)) + { + using (FileStream StreamToZip = new FileStream(fileToZip, FileMode.Open, FileAccess.Read)) + { + string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1); + + ZipEntry ZipEntry = new ZipEntry(fileName); + + ZipStream.PutNextEntry(ZipEntry); + + ZipStream.SetLevel(compressionLevel); + + byte[] buffer = new byte[blockSize]; + + int sizeRead = 0; + + try + { + do + { + sizeRead = StreamToZip.Read(buffer, 0, buffer.Length); + ZipStream.Write(buffer, 0, sizeRead); + } + while (sizeRead > 0); + } + catch + { + + } + + StreamToZip.Close(); + } + + ZipStream.Finish(); + ZipStream.Close(); + } + + ZipFile.Close(); + } + } + + /// + /// 压缩单个文件 + /// + /// 要进行压缩的文件名 + /// 压缩后生成的压缩文件名 + public static void ZipFile(string fileToZip, string zipedFile) + { + //如果文件没有找到,则报错 + if (!File.Exists(fileToZip)) + { + throw new FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!"); + } + + using (FileStream fs = File.OpenRead(fileToZip)) + { + byte[] buffer = new byte[fs.Length]; + fs.Read(buffer, 0, buffer.Length); + fs.Close(); + + using (FileStream ZipFile = File.Create(zipedFile)) + { + using (ZipOutputStream ZipStream = new ZipOutputStream(ZipFile)) + { + string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1); + ZipEntry ZipEntry = new ZipEntry(fileName); + ZipStream.PutNextEntry(ZipEntry); + ZipStream.SetLevel(5); + + ZipStream.Write(buffer, 0, buffer.Length); + ZipStream.Finish(); + ZipStream.Close(); + } + } + } + } + + /// + /// 压缩多个文件到指定路径 + /// + /// 压缩到哪个路径 + /// 压缩文件名称 + public static void ZipFile(List sourceFileNames, string zipFileName) + { + //压缩文件打包 + using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFileName))) + { + s.SetLevel(9); + byte[] buffer = new byte[4096]; + foreach (string file in sourceFileNames) + { + if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 + { + string pPath = ""; + pPath += Path.GetFileName(file); + pPath += "\\"; + ZipSetp(file, s, pPath, sourceFileNames); + } + else // 否则直接压缩文件 + { + + ZipEntry entry = new ZipEntry(Path.GetFileName(file)); + entry.DateTime = DateTime.Now; + s.PutNextEntry(entry); + using (FileStream fs = File.OpenRead(file)) + { + int sourceBytes; + do + { + sourceBytes = fs.Read(buffer, 0, buffer.Length); + s.Write(buffer, 0, sourceBytes); + } while (sourceBytes > 0); + } + } + } + s.Finish(); + s.Close(); + } + } + + + /// + /// 压缩多层目录 + /// + /// 待压缩目录 + /// 压缩后生成的压缩文件名,绝对路径 + public static void ZipFileDirectory(string strDirectory, string zipedFile) + { + using (FileStream ZipFile = File.Create(zipedFile)) + { + using (ZipOutputStream s = new ZipOutputStream(ZipFile)) + { + s.SetLevel(9); + ZipSetp(strDirectory, s, ""); + } + } + } + + /// + /// 压缩多层目录 + /// + /// 待压缩目录 + /// 压缩后生成的压缩文件名,绝对路径 + /// 指定要压缩的文件列表(完全路径) + public static void ZipFileDirectory(string strDirectory, string zipedFile, List files) + { + using (FileStream ZipFile = File.Create(zipedFile)) + { + using (ZipOutputStream s = new ZipOutputStream(ZipFile)) + { + s.SetLevel(9); + ZipSetp(strDirectory, s, "", files); + } + } + } + + /// + /// 递归遍历目录 + /// + /// 需遍历的目录 + /// 压缩输出流对象 + /// The parent path. + /// 需要压缩的文件 + private static void ZipSetp(string strDirectory, ZipOutputStream s, string parentPath, List files = null!) + { + if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar) + { + strDirectory += Path.DirectorySeparatorChar; + } + + string[] filenames = Directory.GetFileSystemEntries(strDirectory); + + byte[] buffer = new byte[4096]; + foreach (string file in filenames)// 遍历所有的文件和目录 + { + if (files != null && !files.Contains(file)) + { + continue; + } + if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 + { + string pPath = parentPath; + pPath += Path.GetFileName(file); + pPath += "\\"; + ZipSetp(file, s, pPath, files!); + } + else // 否则直接压缩文件 + { + //打开压缩文件 + string fileName = parentPath + Path.GetFileName(file); + ZipEntry entry = new ZipEntry(fileName); + + entry.DateTime = DateTime.Now; + + s.PutNextEntry(entry); + using (FileStream fs = File.OpenRead(file)) + { + int sourceBytes; + do + { + sourceBytes = fs.Read(buffer, 0, buffer.Length); + s.Write(buffer, 0, sourceBytes); + } while (sourceBytes > 0); + + } + } + } + } + + /// + /// 解压缩一个 zip 文件。 + /// + /// 压缩文件 + /// 解压目录 + /// zip 文件的密码。 + /// 是否覆盖已存在的文件。 + public static void UnZip(string zipedFile, string strDirectory, bool overWrite, string password) + { + + if (strDirectory == "") + strDirectory = Directory.GetCurrentDirectory(); + if (!strDirectory.EndsWith("\\")) + strDirectory = strDirectory + "\\"; + + using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipedFile))) + { + if (password != null) + { + s.Password = password; + } + ZipEntry theEntry; + + while ((theEntry = s.GetNextEntry()) != null) + { + string directoryName = ""; + string pathToZip = ""; + pathToZip = theEntry.Name; + + if (pathToZip != "") + directoryName = Path.GetDirectoryName(pathToZip) + "\\"; + + string fileName = Path.GetFileName(pathToZip); + + Directory.CreateDirectory(strDirectory + directoryName); + + if (fileName != "") + { + if (File.Exists(strDirectory + directoryName + fileName) && overWrite || !File.Exists(strDirectory + directoryName + fileName)) + { + using (FileStream streamWriter = File.Create(strDirectory + directoryName + fileName)) + { + int size = 2048; + byte[] data = new byte[2048]; + while (true) + { + size = s.Read(data, 0, data.Length); + + if (size > 0) + streamWriter.Write(data, 0, size); + else + break; + } + streamWriter.Close(); + } + } + } + } + + s.Close(); + } + } + + /// + /// 解压缩一个 zip 文件。 + /// + /// 压缩文件 + /// 解压目录 + /// 是否覆盖已存在的文件。 + public static void UnZip(string zipedFile, string strDirectory, bool overWrite) + { + UnZip(zipedFile, strDirectory, overWrite, null!); + } + + /// + /// 解压缩一个 zip 文件。 + /// 覆盖已存在的文件。 + /// + /// 压缩文件 + /// 解压目录 + public static void UnZip(string zipedFile, string strDirectory) + { + UnZip(zipedFile, strDirectory, true); + } + + /// + /// 获取压缩文件中指定类型的文件 + /// + /// 压缩文件 + /// 文件类型(.txt|.exe) + /// 文件名称列表(包含子目录) + public static List GetFiles(string zipedFile, List fileExtension) + { + List files = new List(); + if (!File.Exists(zipedFile)) + { + //return files; + throw new FileNotFoundException(zipedFile); + } + + using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipedFile))) + { + ZipEntry theEntry; + while ((theEntry = s.GetNextEntry()) != null) + { + if (theEntry.IsFile) + { + //Console.WriteLine("Name : {0}", theEntry.Name); + if (fileExtension != null) + { + if (fileExtension.Contains(Path.GetExtension(theEntry.Name))) + { + files.Add(theEntry.Name); + } + } + else + { + files.Add(theEntry.Name); + } + } + } + s.Close(); + } + + return files; + } + + /// + /// 获取压缩文件中的所有文件 + /// + /// 压缩文件 + /// 文件名称列表(包含子目录) + public static List GetFiles(string zipedFile) + { + return GetFiles(zipedFile, null!); + } + + + + }//Class_end + +} \ No newline at end of file diff --git a/SoEasyPlatform/InitProjects/1_Main.cs b/SoEasyPlatform/InitProjects/1_Main.cs new file mode 100644 index 00000000..d6551110 --- /dev/null +++ b/SoEasyPlatform/InitProjects/1_Main.cs @@ -0,0 +1,41 @@ +using Newtonsoft.Json.Linq; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml.Linq; + +namespace SoEasyPlatform +{ + /// + /// 用来初始化整个项目主入口 + /// + public partial class InitTable + { + SqlSugarClient db; + private void InitProjects(SqlSugarClient db) + { + this.db = db; + var directory = FileSugar.MergeUrl(Directory.GetCurrentDirectory(), "wwwroot", "template", "Projects"); + if (!Directory.Exists(directory)) Directory.CreateDirectory(directory); + var slnListPathList = Directory.GetDirectories(directory); + if (slnListPathList == null) return; + try + { + db.BeginTran(); + db.Updateable().SetColumns(it => it.Description == "") +.Where(it => true) +.ExecuteCommand(); + foreach (var sln in slnListPathList) + { + AddSln(sln); + } + db.CommitTran(); + } + catch (System.Exception ex) + { + db.RollbackTran(); + } + } + } +} diff --git a/SoEasyPlatform/InitProjects/2_SlnManager.cs b/SoEasyPlatform/InitProjects/2_SlnManager.cs new file mode 100644 index 00000000..93edf3b2 --- /dev/null +++ b/SoEasyPlatform/InitProjects/2_SlnManager.cs @@ -0,0 +1,76 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; + +namespace SoEasyPlatform +{ + /// + ///项目解决方案管理 + /// + public partial class InitTable + { + int groupId = 0; + private void AddSln(string sln) + { + projectNames = ""; + var slnName = System.IO.Path.GetFileName(sln); + var groupdata = db.Queryable().First(it => it.Name == slnName); + ClearGroup(groupdata); + groupdata = groupdata==null?CreateEmptyProject():groupdata; + if (groupdata.Id == 0) + { + groupId = db.Insertable(groupdata).ExecuteReturnIdentity(); + } + else + { + groupId = groupdata.Id; + } + var ids = AddProjects(sln, slnName); + UpdateProjectGroup(slnName, ids); + } + + private ProjectGroup UpdateProjectGroup(string slnName, List ids) + { + ProjectGroup projectGroup = new ProjectGroup() + { + ProjectIds = ids.ToArray(), + Name = slnName, + ProjectNames = projectNames.TrimEnd(','), + SolutionPath =FileSugar.MergeUrl("c:\\Projects\\" + slnName), + Sort = 100, + Id = groupId, + Description= $"启用文件同步中,点击关闭" + }; + + db.Updateable(projectGroup).ExecuteCommand(); + return projectGroup; + } + + private static ProjectGroup CreateEmptyProject() + { + return new ProjectGroup() + { + ProjectIds = new int[] { }, + Name = "", + ProjectNames = "", + SolutionPath = "", + Sort = 100 + }; + } + + private void ClearGroup(ProjectGroup groupdata) + { + if (groupdata != null) + { + + //db.Deleteable(groupdata).ExecuteCommand(); + db.Deleteable().Where(it => it.SolutionId.Equals(groupdata.Id)).ExecuteCommand(); + db.Deleteable().Where(it => it.SolutionId.Equals(groupdata.Id)).ExecuteCommand(); + db.Deleteable