From 9f587711f09682b0dc148439c0b6a5e19aa1a782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com> Date: Sat, 10 Jun 2023 18:26:18 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=94=AF=E6=8C=81Oracle=E5=BA=93?= =?UTF-8?q?=E3=80=81Oracle=E5=BA=93=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/CommonController.cs | 1 - .../System/CodeGeneratorController.cs | 13 ++- ZR.Admin.WebApi/Extensions/DbExtension.cs | 80 ++++++++++-------- ZR.Admin.WebApi/Extensions/InitTable.cs | 53 ++++++++++++ ZR.Admin.WebApi/appsettings.json | 2 +- .../wwwroot/CodeGenTemplate/sql/Other.txt | 1 + ZR.Admin.WebApi/wwwroot/data.xlsx | Bin 36529 -> 36212 bytes ZR.CodeGenerator/CodeGeneratorTool.cs | 73 ++++++++-------- ZR.CodeGenerator/GenConstants.cs | 4 +- ZR.CodeGenerator/Model/OracleSeq.cs | 11 +++ ZR.CodeGenerator/Model/ReplaceDto.cs | 4 + .../Service/CodeGeneraterService.cs | 14 +++ ZR.CodeGenerator/ZR.CodeGenerator.csproj | 2 +- ZR.Model/System/Article.cs | 2 +- ZR.Model/System/SysBase.cs | 9 ++ ZR.Model/System/SysNotice.cs | 2 +- ZR.Model/System/SysOperLog.cs | 4 +- ZR.Model/System/SysRoleMenu.cs | 1 - ZR.Model/ZR.Model.csproj | 2 +- ZR.Repository/ZR.Repository.csproj | 2 +- ZR.Service/System/SeedDataService.cs | 6 +- ZR.Service/System/SysMenuService.cs | 6 +- document/oracle/seq.txt | 46 ++++++++++ 23 files changed, 239 insertions(+), 99 deletions(-) create mode 100644 ZR.Admin.WebApi/Extensions/InitTable.cs create mode 100644 ZR.Admin.WebApi/wwwroot/CodeGenTemplate/sql/Other.txt create mode 100644 ZR.CodeGenerator/Model/OracleSeq.cs create mode 100644 document/oracle/seq.txt diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs index 47db2f7..20590bc 100644 --- a/ZR.Admin.WebApi/Controllers/CommonController.cs +++ b/ZR.Admin.WebApi/Controllers/CommonController.cs @@ -190,7 +190,6 @@ namespace ZR.Admin.WebApi.Controllers return ToResponse(ResultCode.CUSTOM_ERROR, "导入数据失败"); } var path = Path.Combine(WebHostEnvironment.WebRootPath, "data.xlsx"); - //var sheetNames = MiniExcel.GetSheetNames(path); SeedDataService seedDataService = new(); var result = seedDataService.InitSeedData(path, clean); Console.ForegroundColor = ConsoleColor.Red; diff --git a/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs b/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs index 5aabe55..8941c6a 100644 --- a/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs +++ b/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs @@ -153,6 +153,7 @@ namespace ZR.Admin.WebApi.Controllers { throw new CustomException("表不能为空"); } + var dbType = AppSettings.GetAppConfig(GenConstants.Gen_conn_dbType, 0); string[] tableNames = tables.Split(',', StringSplitOptions.RemoveEmptyEntries); int result = 0; foreach (var tableName in tableNames) @@ -160,15 +161,18 @@ namespace ZR.Admin.WebApi.Controllers var tabInfo = _CodeGeneraterService.GetTableInfo(dbName, tableName); if (tabInfo != null) { + List seqs = new(); GenTable genTable = CodeGeneratorTool.InitTable(dbName, HttpContext.GetName(), tableName, tabInfo?.Description); genTable.TableId = GenTableService.ImportGenTable(genTable); - + if (dbType == 3) + { + seqs = _CodeGeneraterService.GetAllOracleSeqs(dbName); + } if (genTable.TableId > 0) { //保存列信息 List dbColumnInfos = _CodeGeneraterService.GetColumnInfo(dbName, tableName); - List genTableColumns = CodeGeneratorTool.InitGenTableColumn(genTable, dbColumnInfos); - + List genTableColumns = CodeGeneratorTool.InitGenTableColumn(genTable, dbColumnInfos, seqs); GenTableColumnService.DeleteGenTableColumnByTableName(tableName); GenTableColumnService.InsertGenTableColumn(genTableColumns); genTable.Columns = genTableColumns; @@ -264,10 +268,11 @@ namespace ZR.Admin.WebApi.Controllers //自定义路径 if (genTableInfo.GenType == "1") { + var genPath = genTableInfo.GenPath; string tempPath = WebHostEnvironment.ContentRootPath; var parentPath = tempPath[..tempPath.LastIndexOf(@"\")]; //代码生成文件夹路径 - dto.GenCodePath = genTableInfo.GenPath.IsEmpty() ? parentPath : genTableInfo.GenPath; + dto.GenCodePath = (genPath.IsEmpty() || genPath.Equals("/")) ? parentPath : genTableInfo.GenPath; } else { diff --git a/ZR.Admin.WebApi/Extensions/DbExtension.cs b/ZR.Admin.WebApi/Extensions/DbExtension.cs index e9d7641..5840448 100644 --- a/ZR.Admin.WebApi/Extensions/DbExtension.cs +++ b/ZR.Admin.WebApi/Extensions/DbExtension.cs @@ -1,15 +1,16 @@ using Infrastructure; using Infrastructure.Extensions; -using Infrastructure.Helper; using SqlSugar; using SqlSugar.IOC; -using System.Reflection; using ZR.Admin.WebApi.Framework; using ZR.Model; using ZR.Model.System; namespace ZR.Admin.WebApi.Extensions { + /// + /// sqlsugar 数据处理 + /// public static class DbExtension { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); @@ -63,9 +64,9 @@ namespace ZR.Admin.WebApi.Extensions }); }); - if(Configuration["InitDb"].ParseToBool() == true && environment.IsDevelopment()) + if (Configuration["InitDb"].ParseToBool() == true && environment.IsDevelopment()) { - InitDb(); + InitTable.InitDb(); } } @@ -78,7 +79,7 @@ namespace ZR.Admin.WebApi.Extensions private static void SetSugarAop(SqlSugarClient db, IocConfig iocConfig, ICacheService cache) { var config = db.GetConnectionScope(iocConfig.ConfigId).CurrentConnectionConfig; - + string configId = config.ConfigId; db.GetConnectionScope(configId).Aop.OnLogExecuting = (sql, pars) => { @@ -101,7 +102,6 @@ namespace ZR.Admin.WebApi.Extensions logger.Info(log); } }; - db.GetConnectionScope(configId).Aop.OnError = (ex) => { var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value)); @@ -109,10 +109,10 @@ namespace ZR.Admin.WebApi.Extensions string sql = "【错误SQL】" + UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n"; logger.Error(ex, $"{sql}\r\n{ex.Message}\r\n{ex.StackTrace}"); }; - db.GetConnectionScope(configId).Aop.DataExecuting = (oldValue, entiyInfo) => { }; + db.GetConnectionScope(configId).CurrentConnectionConfig.MoreSettings = new ConnMoreSettings() { IsAutoRemoveDataCache = true @@ -122,20 +122,6 @@ namespace ZR.Admin.WebApi.Extensions DataInfoCacheService = cache, EntityService = (c, p) => { - p.DbTableName = p.DbTableName.FirstLowerCase(); - p.DbColumnName = p.DbColumnName.FirstLowerCase(); - - if (db.GetConnectionScope(configId).CurrentConnectionConfig.DbType == DbType.PostgreSQL) - { - if (p.DataType != null && p.DataType.Contains("nvarchar")) - { - p.DataType = "text"; - } - if (c.Name == nameof(SysMenu.IsCache) || c.Name == nameof(SysMenu.IsFrame)) - { - p.DataType = "char(1)"; - } - } if (p.IsPrimarykey == true)//主键不能为null { p.IsNullable = false; @@ -148,26 +134,46 @@ namespace ZR.Admin.WebApi.Extensions { p.IsNullable = true; } + + if (config.DbType == DbType.PostgreSQL) + { + if (c.Name == nameof(SysMenu.IsCache) || c.Name == nameof(SysMenu.IsFrame)) + { + p.DataType = "char(1)"; + } + } + #region 兼容Oracle + if (config.DbType == DbType.Oracle) + { + if (p.IsIdentity == true) + { + if (p.EntityName == nameof(SysUser)) + { + p.OracleSequenceName = "SEQ_SYS_USER_USERID"; + } + else if (p.EntityName == nameof(SysRole)) + { + p.OracleSequenceName = "SEQ_SYS_ROLE_ROLEID"; + } + else if (p.EntityName == nameof(SysDept)) + { + p.OracleSequenceName = "SEQ_SYS_DEPT_DEPTID"; + } + else if (p.EntityName == nameof(SysMenu)) + { + p.OracleSequenceName = "SEQ_SYS_MENU_MENUID"; + } + else + { + p.OracleSequenceName = "SEQ_ID"; + } + } + } + #endregion } }; } - /// - /// 创建db、表 - /// - public static void InitDb() - { - var db = DbScoped.SugarScope; - //建库:如果不存在创建数据库存在不会重复创建 - db.DbMaintenance.CreateDatabase();// 注意 :Oracle和个别国产库需不支持该方法,需要手动建库 - - var baseType = typeof(SysBase); - var entityes = AssemblyUtils.GetAllTypes().Where(p => !p.IsAbstract && p != baseType && p.GetCustomAttribute() != null).ToArray(); - - //23个表 - db.CodeFirst.InitTables(entityes); - } - private static object GetParsValue(SugarParameter x) { if (x.DbType == System.Data.DbType.String || x.DbType == System.Data.DbType.DateTime || x.DbType == System.Data.DbType.String) diff --git a/ZR.Admin.WebApi/Extensions/InitTable.cs b/ZR.Admin.WebApi/Extensions/InitTable.cs new file mode 100644 index 0000000..543f627 --- /dev/null +++ b/ZR.Admin.WebApi/Extensions/InitTable.cs @@ -0,0 +1,53 @@ +using SqlSugar.IOC; +using ZR.Model.Models; +using ZR.Model.System; +using ZR.Model.System.Generate; + +namespace ZR.Admin.WebApi.Extensions +{ + /// + /// 初始化表 + /// + public class InitTable + { + /// + /// 创建db、表 + /// + public static void InitDb() + { + var db = DbScoped.SugarScope; + //建库:如果不存在创建数据库存在不会重复创建 + db.DbMaintenance.CreateDatabase();// 注意 :Oracle和个别国产库需不支持该方法,需要手动建库 + + //var baseType = typeof(SysBase); + //var entityes = AssemblyUtils.GetAllTypes().Where(p => !p.IsAbstract && p != baseType && p.GetCustomAttribute() != null).ToArray(); + //db.CodeFirst.InitTables(entityes); + + //23个表,建议先使用下面方法初始化表,方便排查问题 + db.CodeFirst.InitTables(typeof(SysUser)); + db.CodeFirst.InitTables(typeof(SysRole)); + db.CodeFirst.InitTables(typeof(SysDept)); + db.CodeFirst.InitTables(typeof(SysPost)); + db.CodeFirst.InitTables(typeof(SysFile)); + db.CodeFirst.InitTables(typeof(SysConfig)); + db.CodeFirst.InitTables(typeof(SysNotice)); + db.CodeFirst.InitTables(typeof(SysLogininfor)); + db.CodeFirst.InitTables(typeof(SysOperLog)); + db.CodeFirst.InitTables(typeof(SysMenu)); + db.CodeFirst.InitTables(typeof(SysRoleMenu)); + db.CodeFirst.InitTables(typeof(SysRoleDept)); + db.CodeFirst.InitTables(typeof(SysUserRole)); + db.CodeFirst.InitTables(typeof(SysUserPost)); + db.CodeFirst.InitTables(typeof(SysTasks)); + db.CodeFirst.InitTables(typeof(SysTasksLog)); + db.CodeFirst.InitTables(typeof(CommonLang)); + db.CodeFirst.InitTables(typeof(GenTable)); + db.CodeFirst.InitTables(typeof(GenTableColumn)); + db.CodeFirst.InitTables(typeof(Article)); + db.CodeFirst.InitTables(typeof(ArticleCategory)); + db.CodeFirst.InitTables(typeof(SysDictData)); + db.CodeFirst.InitTables(typeof(SysDictType)); + } + + } +} diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json index 3f35065..7c51eef 100644 --- a/ZR.Admin.WebApi/appsettings.json +++ b/ZR.Admin.WebApi/appsettings.json @@ -36,7 +36,7 @@ "DemoMode": false, //是否演示模式 "Upload": { "uploadUrl": "http://localhost:8888", //本地存储资源访问路径 - "localSavePath": "uploads", //本地上传默认文件存储目录 wwwroot/uploads + "localSavePath": "uploads", //本地上传默认文件存储目录 wwwroot/uploads, 如果saveType= 2 (请使用完整路径,比如 /home/resource) "maxSize": 15, //上传文件大小限制 15M "notAllowedExt": [ ".bat", ".exe", ".jar", ".js" ] }, diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/sql/Other.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/sql/Other.txt new file mode 100644 index 0000000..c429c89 --- /dev/null +++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/sql/Other.txt @@ -0,0 +1 @@ +请勾选 添加菜单 ,将会自动导入菜单到数据库中 \ No newline at end of file diff --git a/ZR.Admin.WebApi/wwwroot/data.xlsx b/ZR.Admin.WebApi/wwwroot/data.xlsx index a5c36f11f29767c01bba31a8ed4660f5854b734e..5546be9ccb3d63b605c2f1ab6537651264823db5 100644 GIT binary patch delta 23805 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 delta 24156 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 f == 5), ShowBtnTruncate = dto.GenTable.Options.CheckedBtn.Any(f => f == 6), ShowBtnMultiDel = dto.GenTable.Options.CheckedBtn.Any(f => f == 7), + ViewFileName = dto.GenTable.BusinessName.FirstUpperCase() }; var columns = dto.GenTable.Columns; @@ -67,7 +68,7 @@ namespace ZR.CodeGenerator GenerateControllers(replaceDto, dto); if (dto.VueVersion == 3) { - GenerateVue3Views(dto); + GenerateVue3Views(replaceDto, dto); } else { @@ -182,7 +183,7 @@ namespace ZR.CodeGenerator replaceDto.VueViewFormHtml = GenerateCurdForm(); var tpl = JnHelper.ReadTemplate(CodeTemplateDir, fileName); - var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{generateDto.GenTable.BusinessName.FirstUpperCase()}.vue"); + var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue"); generateDto.GenCodes.Add(new GenCode(6, "index.vue", fullPath, tpl.Render())); } @@ -191,7 +192,7 @@ namespace ZR.CodeGenerator /// vue3 /// /// - private static void GenerateVue3Views(GenerateDto generateDto) + private static void GenerateVue3Views(ReplaceDto replaceDto, GenerateDto generateDto) { string fileName = generateDto.GenTable.TplCategory switch { @@ -206,7 +207,7 @@ namespace ZR.CodeGenerator tpl.Set("options", generateDto.GenTable?.Options); var result = tpl.Render(); - var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{generateDto.GenTable.BusinessName.FirstUpperCase()}.vue"); + var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue"); generateDto.GenCodes.Add(new GenCode(16, "index.vue", fullPath, result)); } @@ -240,21 +241,13 @@ namespace ZR.CodeGenerator /// public static void GenerateSql(GenerateDto generateDto) { - var tempName = ""; - switch (generateDto.DbType) + string tempName = generateDto.DbType switch { - case 0: - tempName = "MySqlTemplate"; - break; - case 1: - tempName = "SqlTemplate"; - break; - case 4: - tempName = "PgSql"; - break; - default: - break; - } + 0 => "MySqlTemplate", + 1 => "SqlTemplate", + 4 => "PgSql", + _ => "Other", + }; var tpl = JnHelper.ReadTemplate(CodeTemplateDir, Path.Combine("sql", $"{tempName}.txt")); tpl.Set("parentId", generateDto.GenTable?.Options?.ParentMenuId ?? 0); var result = tpl.Render(); @@ -315,18 +308,8 @@ namespace ZR.CodeGenerator } } } - return tableName.UnderScoreToCamelCase(); - } - - /// - /// 获取前端标签名 - /// - /// - /// - /// - public static string GetLabelName(string columnDescription, string columnName) - { - return string.IsNullOrEmpty(columnDescription) ? columnName : columnDescription; + //return tableName.UnderScoreToCamelCase(); + return tableName.ConvertToPascal("_"); } /// @@ -343,7 +326,7 @@ namespace ZR.CodeGenerator catch (Exception ex) { Console.WriteLine(ex.Message); - return ""; + return str; } } @@ -357,8 +340,8 @@ namespace ZR.CodeGenerator sDatatype = sDatatype.ToLower(); string sTempDatatype = sDatatype switch { - "int" or "number" or "integer" or "smallint" or "int4" or "int8" or "int2" => "int", - "bigint" => "long", + "int" or "integer" or "smallint" or "int4" or "int8" or "int2" => "int", + "bigint" or "number" => "long", "tinyint" => "byte", "numeric" or "real" or "float" => "float", "decimal" or "numer(8,2)" or "numeric" => "decimal", @@ -389,8 +372,8 @@ namespace ZR.CodeGenerator DbName = dbName, BaseNameSpace = "ZR.",//导入默认命名空间前缀 ModuleName = "business",//导入默认模块名 - ClassName = GetClassName(tableName).FirstUpperCase(), - BusinessName = tableName.UnderScoreToCamelCase().FirstUpperCase(), + ClassName = GetClassName(tableName), + BusinessName = GetClassName(tableName), FunctionAuthor = AppSettings.GetConfig(GenConstants.Gen_author), TableName = tableName, TableComment = desc, @@ -412,12 +395,13 @@ namespace ZR.CodeGenerator /// /// /// - public static List InitGenTableColumn(GenTable genTable, List dbColumnInfos) + /// + public static List InitGenTableColumn(GenTable genTable, List dbColumnInfos, List seqs = null) { List genTableColumns = new(); foreach (var column in dbColumnInfos) { - genTableColumns.Add(InitColumnField(genTable, column)); + genTableColumns.Add(InitColumnField(genTable, column, seqs)); } return genTableColumns; } @@ -428,17 +412,26 @@ namespace ZR.CodeGenerator /// /// /// - private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column) + private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column, List seqs) { + var dbType = AppSettings.Get(GenConstants.Gen_conn_dbType); + var dataType = column.DataType; + if (dbType == 3) + { + dataType = column.OracleDataType; + var seqName = $"SEQ_{genTable.TableName}_{column.DbColumnName}"; + var isIdentity = seqs.Any(f => seqName.Equals(f.SEQUENCE_NAME, StringComparison.CurrentCultureIgnoreCase)); + column.IsIdentity = isIdentity; + } GenTableColumn genTableColumn = new() { ColumnName = column.DbColumnName.FirstLowerCase(), ColumnComment = column.ColumnDescription, IsPk = column.IsPrimarykey, - ColumnType = column.DataType, + ColumnType = dataType, TableId = genTable.TableId, TableName = genTable.TableName, - CsharpType = GetCSharpDatatype(column.DataType), + CsharpType = GetCSharpDatatype(dataType), CsharpField = column.DbColumnName.ConvertToPascal("_"), IsRequired = !column.IsNullable, IsIncrement = column.IsIdentity, diff --git a/ZR.CodeGenerator/GenConstants.cs b/ZR.CodeGenerator/GenConstants.cs index 057cc2f..c2563aa 100644 --- a/ZR.CodeGenerator/GenConstants.cs +++ b/ZR.CodeGenerator/GenConstants.cs @@ -15,7 +15,7 @@ namespace ZR.CodeGenerator /// /// InputDto输入实体是不包含字段 /// - public static readonly string[] inputDtoNoField = new string[] { "createTime", "updateTime", "addtime", "create_time", "update_time" }; + public static readonly string[] inputDtoNoField = new string[] { "createTime", "updateTime", "addtime", "create_time", "update_time", "create_by", "update_by" }; /// /// 图片字段 /// @@ -27,7 +27,7 @@ namespace ZR.CodeGenerator /// /// 单选按钮字段 /// - public static readonly string[] radioFiled = new string[] { "status", "state", "is"}; + public static readonly string[] radioFiled = new string[] { "status", "state", "is" }; /// diff --git a/ZR.CodeGenerator/Model/OracleSeq.cs b/ZR.CodeGenerator/Model/OracleSeq.cs new file mode 100644 index 0000000..6a56a30 --- /dev/null +++ b/ZR.CodeGenerator/Model/OracleSeq.cs @@ -0,0 +1,11 @@ +namespace ZR.CodeGenerator.Model +{ + /// + /// Oracle库序列 + /// + public class OracleSeq + { + public string SEQUENCE_NAME { get; set; } + public long LAST_NUMBER { get; set; } + } +} diff --git a/ZR.CodeGenerator/Model/ReplaceDto.cs b/ZR.CodeGenerator/Model/ReplaceDto.cs index 325fd48..6ea178f 100644 --- a/ZR.CodeGenerator/Model/ReplaceDto.cs +++ b/ZR.CodeGenerator/Model/ReplaceDto.cs @@ -65,5 +65,9 @@ namespace ZR.CodeGenerator.Model /// 是否有编辑器 /// public int ShowEditor { get; set; } + /// + /// vue页面文件名 + /// + public string ViewFileName { get; set; } } } diff --git a/ZR.CodeGenerator/Service/CodeGeneraterService.cs b/ZR.CodeGenerator/Service/CodeGeneraterService.cs index 95f44c6..bbe2557 100644 --- a/ZR.CodeGenerator/Service/CodeGeneraterService.cs +++ b/ZR.CodeGenerator/Service/CodeGeneraterService.cs @@ -2,6 +2,7 @@ using SqlSugar; using System.Collections.Generic; using System.Linq; +using ZR.CodeGenerator.Model; using ZR.Model; namespace ZR.CodeGenerator.Service @@ -72,5 +73,18 @@ namespace ZR.CodeGenerator.Service { return GetSugarDbContext(dbName).DbMaintenance.GetColumnInfosByTableName(tableName, true); } + + /// + /// 获取Oracle所有序列 + /// + /// + /// + public List GetAllOracleSeqs(string dbName) + { + string sql = "SELECT * FROM USER_SEQUENCES"; + var seqs = GetSugarDbContext(dbName).Ado.SqlQuery(sql); + + return seqs.ToList(); + } } } diff --git a/ZR.CodeGenerator/ZR.CodeGenerator.csproj b/ZR.CodeGenerator/ZR.CodeGenerator.csproj index 71788a3..a1a2040 100644 --- a/ZR.CodeGenerator/ZR.CodeGenerator.csproj +++ b/ZR.CodeGenerator/ZR.CodeGenerator.csproj @@ -12,6 +12,6 @@ - + diff --git a/ZR.Model/System/Article.cs b/ZR.Model/System/Article.cs index 558deb0..52854ae 100644 --- a/ZR.Model/System/Article.cs +++ b/ZR.Model/System/Article.cs @@ -33,7 +33,7 @@ namespace ZR.Model.System /// /// 文章内容 /// - [SugarColumn(ColumnDescription = "文章内容", ColumnDataType = "text")] + [SugarColumn(ColumnDescription = "文章内容", ColumnDataType = StaticConfig.CodeFirst_BigString)] public string Content { get; set; } /// /// 作者名 diff --git a/ZR.Model/System/SysBase.cs b/ZR.Model/System/SysBase.cs index 5618c83..b46ce8e 100644 --- a/ZR.Model/System/SysBase.cs +++ b/ZR.Model/System/SysBase.cs @@ -16,17 +16,26 @@ namespace ZR.Model.System [ExcelIgnore] public string Create_by { get; set; } + /// + /// 创建时间 + /// [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true)] [JsonProperty(propertyName: "CreateTime")] [ExcelColumn(Format = "yyyy-MM-dd HH:mm:ss")] public DateTime Create_time { get; set; } = DateTime.Now; + /// + /// 更新人 + /// [JsonIgnore] [JsonProperty(propertyName: "UpdateBy")] [SugarColumn(IsOnlyIgnoreInsert = true, Length = 64, IsNullable = true)] [ExcelIgnore] public string Update_by { get; set; } + /// + /// 更新时间 + /// //[JsonIgnore] [SugarColumn(IsOnlyIgnoreInsert = true, IsNullable = true)] [JsonProperty(propertyName: "UpdateTime")] diff --git a/ZR.Model/System/SysNotice.cs b/ZR.Model/System/SysNotice.cs index de82a33..ff00e34 100644 --- a/ZR.Model/System/SysNotice.cs +++ b/ZR.Model/System/SysNotice.cs @@ -30,7 +30,7 @@ namespace ZR.Model.System /// /// 公告内容 /// - [SugarColumn(ColumnName = "notice_content", ColumnDataType = "text")] + [SugarColumn(ColumnName = "notice_content", ColumnDataType = StaticConfig.CodeFirst_BigString)] public string NoticeContent { get; set; } /// /// 公告状态 (0正常 1关闭) diff --git a/ZR.Model/System/SysOperLog.cs b/ZR.Model/System/SysOperLog.cs index 3e33e21..3eed289 100644 --- a/ZR.Model/System/SysOperLog.cs +++ b/ZR.Model/System/SysOperLog.cs @@ -72,13 +72,13 @@ namespace ZR.Model.System /// /// 请求参数 /// - [SugarColumn(Length = 2000)] + [SugarColumn(Length = 4000)] public string OperParam { get; set; } /// /// 返回参数 /// - [SugarColumn(ColumnDataType = "text")] + [SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)] public string JsonResult { get; set; } /// diff --git a/ZR.Model/System/SysRoleMenu.cs b/ZR.Model/System/SysRoleMenu.cs index 94a6fa6..9a037a4 100644 --- a/ZR.Model/System/SysRoleMenu.cs +++ b/ZR.Model/System/SysRoleMenu.cs @@ -1,6 +1,5 @@ using Newtonsoft.Json; using SqlSugar; -using System; namespace ZR.Model.System { diff --git a/ZR.Model/ZR.Model.csproj b/ZR.Model/ZR.Model.csproj index 848f750..7efcd39 100644 --- a/ZR.Model/ZR.Model.csproj +++ b/ZR.Model/ZR.Model.csproj @@ -9,7 +9,7 @@ - + diff --git a/ZR.Repository/ZR.Repository.csproj b/ZR.Repository/ZR.Repository.csproj index b100ff4..22ea936 100644 --- a/ZR.Repository/ZR.Repository.csproj +++ b/ZR.Repository/ZR.Repository.csproj @@ -15,6 +15,6 @@ - + diff --git a/ZR.Service/System/SeedDataService.cs b/ZR.Service/System/SeedDataService.cs index ddb858a..62bd9a4 100644 --- a/ZR.Service/System/SeedDataService.cs +++ b/ZR.Service/System/SeedDataService.cs @@ -49,14 +49,12 @@ namespace ZR.Service.System public (string, object, object) InitMenuData(List data) { var db = DbScoped.SugarScope; - db.Ado.BeginTran(); var x = db.Storageable(data) .SplitInsert(it => it.NotAny()) .WhereColumns(it => it.MenuId)//如果不是主键可以这样实现(多字段it=>new{it.x1,it.x2}) .ToStorage(); var result = x.AsInsertable.OffIdentity().ExecuteCommand();//插入可插入部分; - db.Ado.CommitTran(); - + string msg = $"[菜单数据] 插入{x.InsertList.Count} 错误数据{x.ErrorList.Count} 总共{x.TotalList.Count}"; return (msg, x.ErrorList, x.IgnoreList); } @@ -89,7 +87,7 @@ namespace ZR.Service.System .SplitInsert(it => it.NotAny()) .WhereColumns(it => it.DeptId) .ToStorage(); - var result = x.AsInsertable.ExecuteCommand(); + var result = x.AsInsertable.OffIdentity().ExecuteCommand(); string msg = $"[部门数据] 插入{x.InsertList.Count} 错误数据{x.ErrorList.Count} 总共{x.TotalList.Count}"; return (msg, x.ErrorList, x.IgnoreList); diff --git a/ZR.Service/System/SysMenuService.cs b/ZR.Service/System/SysMenuService.cs index 1a267d5..cb989f6 100644 --- a/ZR.Service/System/SysMenuService.cs +++ b/ZR.Service/System/SysMenuService.cs @@ -660,8 +660,10 @@ namespace ZR.Service //Insert(menuList); var x = Storageable(menuList) - .WhereColumns(it => new { it.MenuName, it.ParentId }) - .ToStorage(); + .SplitInsert(it => !it.Any()) + .SplitUpdate(it => !it.Any()) + .WhereColumns(it => new { it.MenuName, it.ParentId }) + .ToStorage(); x.AsInsertable.ExecuteCommand();//插入可插入部分; x.AsUpdateable.ExecuteCommand(); } diff --git a/document/oracle/seq.txt b/document/oracle/seq.txt new file mode 100644 index 0000000..c8d5468 --- /dev/null +++ b/document/oracle/seq.txt @@ -0,0 +1,46 @@ + +--通用序列id +create sequence SEQ_ID +minvalue 1 +maxvalue 99999999 +start with 1 +increment by 1 +nocache +order; + +--角色表序列id +create sequence SEQ_SYS_ROLE_ROLEID +minvalue 10 +maxvalue 99999999 +start with 10 +increment by 1 +nocache +order; + +--菜单表序列id +create sequence SEQ_SYS_MENU_MENUID +minvalue 2000 +maxvalue 99999999 +start with 2000 +increment by 1 +nocache +order; + +--用户表序列id +create sequence SEQ_SYS_USER_USERID +minvalue 100 +maxvalue 99999999 +start with 1 +increment by 100 +nocache +order; + +--部门表序列id +create sequence SEQ_SYS_DEPT_DEPTID +minvalue 200 +maxvalue 99999999 +start with 200 +increment by 1 +nocache +order; +