diff --git a/.gitignore b/.gitignore index c516947..34b14f9 100644 --- a/.gitignore +++ b/.gitignore @@ -262,3 +262,4 @@ __pycache__/ /ZRAdmin/Properties/launchSettings.json /ZRAdmin/Properties/PublishProfiles /ZR.Admin.WebApi/appsettings.Stage.json +/CodeGenerate diff --git a/Infrastructure/OptionsSetting.cs b/Infrastructure/OptionsSetting.cs index 4aa2b2e..fb677bb 100644 --- a/Infrastructure/OptionsSetting.cs +++ b/Infrastructure/OptionsSetting.cs @@ -7,7 +7,9 @@ namespace Infrastructure public class OptionsSetting { public static string ConnAdmin = "Conn_admin"; + public static string Conn = "ConnDynamic"; public static string DbType = "DbType"; + public static string CodeGenDbType = "CodeGenDbType"; public static string DbKey = "DbKey"; public string Conn_Admin { get; set; } diff --git a/README.md b/README.md index b86af5e..0983811 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Vue版前端技术栈 :基于vue、vuex、vue-router 、vue-cli 、axios 和 e 日志管理:NLog、登录日志、操作日志 -工具类:验证码、丰富公共功能 +工具类:验证码、丰富公共功能、代码生成 ## 🍄快速启动 需要安装:VS2019(最新版)、npm或yarn(最新版) @@ -59,6 +59,7 @@ Vue版前端技术栈 :基于vue、vuex、vue-router 、vue-cli 、axios 和 e 13. [X] 在线构建器:拖动表单元素生成相应的VUE代码。 14. [X] 任务系统:基于Quartz.NET定时任务执行。 15. [X] 文章管理:可以写文章记录。 +16. [X] 代码生成:可以一键生成前后端代码。 ## 🍎演示图 @@ -82,7 +83,15 @@ Vue版前端技术栈 :基于vue、vuex、vue-router 、vue-cli 、axios 和 e - + + + + + + + + + ## 🎉优势 diff --git a/ZR.Admin.WebApi/Controllers/BaseController.cs b/ZR.Admin.WebApi/Controllers/BaseController.cs index 49413f1..119d7c4 100644 --- a/ZR.Admin.WebApi/Controllers/BaseController.cs +++ b/ZR.Admin.WebApi/Controllers/BaseController.cs @@ -16,34 +16,36 @@ namespace ZR.Admin.WebApi.Controllers public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss"; public static string TIME_FORMAT_FULL_2 = "MM-dd HH:mm:ss"; - protected IActionResult SUCCESS(object data, string timeFormatStr = "MM-dd HH:mm:ss") + protected IActionResult SUCCESS(object data, string timeFormatStr = "yyyy-MM-dd HH:mm:ss") { string jsonStr = GetJsonStr(GetApiResult(data != null ? ResultCode.SUCCESS : ResultCode.FAIL, data), timeFormatStr); return Content(jsonStr, "application/json"); } + protected IActionResult ToRespose(ResultCode resultCode, object data = null) + { + string jsonStr = GetJsonStr(GetApiResult(resultCode, data), ""); + return Content(jsonStr, "application/json"); + } + /// /// json输出带时间格式的 /// /// /// /// - protected IActionResult OutputJson(ApiResult apiResult, string timeFormatStr = "MM-dd HH:mm:ss") + protected IActionResult OutputJson(ApiResult apiResult, string timeFormatStr = "yyyy-MM-dd HH:mm:ss") { string jsonStr = GetJsonStr(apiResult, timeFormatStr); return Content(jsonStr, "application/json"); } - protected IActionResult OutputJson(long rows, string timeFormatStr = "MM-dd HH:mm:ss") + protected IActionResult OutputJson(long rows, string timeFormatStr = "yyyy-MM-dd HH:mm:ss") { string jsonStr = GetJsonStr(ToJson(rows), timeFormatStr); return Content(jsonStr, "application/json"); } - protected string SerializeObject(object obj) - { - return JsonConvert.SerializeObject(obj); - } /// /// 响应返回结果 diff --git a/ZR.Admin.WebApi/Controllers/CodeGeneratorController.cs b/ZR.Admin.WebApi/Controllers/CodeGeneratorController.cs new file mode 100644 index 0000000..7cffe87 --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/CodeGeneratorController.cs @@ -0,0 +1,90 @@ +using Infrastructure; +using Infrastructure.Attribute; +using Infrastructure.Enums; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using System.Collections.Generic; +using ZR.Admin.WebApi.Filters; +using ZR.CodeGenerator; +using ZR.CodeGenerator.Model; +using ZR.CodeGenerator.Service; +using ZR.Model; +using ZR.Model.Vo; + +namespace ZR.Admin.WebApi.Controllers +{ + /// + /// 代码生成 + /// + [Route("tool/gen")] + public class CodeGeneratorController : BaseController + { + private CodeGeneraterService _CodeGeneraterService = new CodeGeneraterService(); + + /// + /// 获取所有数据库的信息 + /// + /// + [HttpGet("getDbList")] + [ActionPermissionFilter(Permission = "tool:gen:list")] + public IActionResult GetListDataBase() + { + var dbList = _CodeGeneraterService.GetAllDataBases(); + var defaultDb = dbList.Count > 0 ? dbList[0] : null; + return SUCCESS(new { dbList, defaultDb }); + } + + /// + ///获取所有表根据数据名 + /// + /// 数据库名 + /// 表名 + /// 分页信息 + /// + [HttpGet("getTableList")] + [ActionPermissionFilter(Permission = "tool:gen:list")] + public IActionResult FindListTable(string dbName, string tableName, PagerInfo pager) + { + List list = _CodeGeneraterService.GetAllTables(dbName, tableName, pager); + var vm = new VMPageResult(list, pager); + + return SUCCESS(vm); + } + + /// + /// 获取表格列 + /// + /// + /// + /// + [HttpGet("getColumnInfo")] + [ActionPermissionFilter(Permission = "tool:gen:list")] + public IActionResult QueryColumnInfo(string dbName, string tableName) + { + if (string.IsNullOrEmpty(dbName) || string.IsNullOrEmpty(tableName)) + return ToRespose(ResultCode.PARAM_ERROR); + + return SUCCESS(_CodeGeneraterService.GetColumnInfo(dbName, tableName)); + } + + /// + /// 代码生成器 + /// + /// 数据传输对象 + /// + [HttpPost("genCode")] + [Log(Title = "代码生成", BusinessType = BusinessType.GENCODE)] + [ActionPermissionFilter(Permission = "tool:gen:code")] + public IActionResult Generate([FromBody] GenerateDto dto) + { + if (string.IsNullOrEmpty(dto.tableName)) + { + throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空"); + } + DbTableInfo dbTableInfo = new() { Name = dto.tableName }; + CodeGeneratorTool.Generate(dbTableInfo, dto); + + return SUCCESS(dbTableInfo); + } + } +} diff --git a/ZR.Admin.WebApi/Extensions/EntityExtension.cs b/ZR.Admin.WebApi/Extensions/EntityExtension.cs index d518656..c472ed5 100644 --- a/ZR.Admin.WebApi/Extensions/EntityExtension.cs +++ b/ZR.Admin.WebApi/Extensions/EntityExtension.cs @@ -10,13 +10,13 @@ namespace ZR.Admin.WebApi.Extensions { var types = source.GetType(); - var worker = new IdWorker(1, 1); - if (types.GetProperty("ID") != null) - { - long id = worker.NextId(); + //var worker = new IdWorker(1, 1); + //if (types.GetProperty("ID") != null) + //{ + // long id = worker.NextId(); - types.GetProperty("ID").SetValue(source, id.ToString(), null); - } + // types.GetProperty("ID").SetValue(source, id.ToString(), null); + //} if (types.GetProperty("CreateTime") != null) { diff --git a/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs b/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs index 88258d7..1f87286 100644 --- a/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs +++ b/ZR.Admin.WebApi/Filters/ActionPermissionFilter.cs @@ -54,7 +54,7 @@ namespace ZR.Admin.WebApi.Filters bool isDemoMode = ConfigUtils.Instance.GetAppConfig("DemoMode", false); //演示公开环境屏蔽权限 - string[] denyPerms = new string[] { "update", "add", "remove", "add", "edit", "delete", "import", "run", "start", "stop", "clear" }; + string[] denyPerms = new string[] { "update", "add", "remove", "add", "edit", "delete", "import", "run", "start", "stop", "clear", "code" }; if (isDemoMode && (denyPerms.Any(f => Permission.ToLower().Contains(f.ToLower())) || Permission.Equals("system"))) { context.Result = new JsonResult(new { code = ResultCode.FORBIDDEN, msg = "演示模式 , 不允许操作" }); diff --git a/ZR.Admin.WebApi/Template/ControllersTemplate.txt b/ZR.Admin.WebApi/Template/ControllersTemplate.txt new file mode 100644 index 0000000..6d8d8b2 --- /dev/null +++ b/ZR.Admin.WebApi/Template/ControllersTemplate.txt @@ -0,0 +1,134 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using ZR.Admin.WebApi.Filters; +using ZR.Admin.WebApi.Controllers; +using ZR.Service.Business; +using SqlSugar; +using Infrastructure; +using Infrastructure.Attribute; +using Infrastructure.Enums; +using Infrastructure.Model; +using Mapster; +using ZR.Admin.WebApi.Extensions; +using {ModelsNamespace}.Dto; +using {ModelsNamespace}.Models; + +namespace ZRAdmin.Controllers +{ + /// + /// 代码自动生成 + /// + + [Verify] + [Route("bus/{ModelName}")] + public class {ControllerName}Controller: BaseController + { + /// + /// {FileName}接口 + /// + private readonly I{ServiceName} _{ServiceName}; + + public {ControllerName}Controller(I{ServiceName} {ServiceName}) + { + _{ServiceName} = {ServiceName}; + } + + /// + /// 查询{FileName}列表 + /// + /// + [HttpGet("list")] + [ActionPermissionFilter(Permission = "{Permission}:list")] + public IActionResult Query([FromQuery] {ModelName}QueryDto parm) + { + //开始拼装查询条件 + var predicate = Expressionable.Create<{ModelName}>(); + + //TODO 搜索条件 + //predicate = predicate.And(m => m.Name.Contains(parm.Name)); + + var response = _{ServiceName}.GetPages(predicate.ToExpression(), parm); + + return SUCCESS(response); + } + + /// + /// 查询{FileName}详情 + /// + /// + /// + [HttpGet("{{primaryKey}}")] + [ActionPermissionFilter(Permission = "{Permission}:query")] + public IActionResult Get({KeyTypeName} {primaryKey}) + { + var response = _{ServiceName}.GetId({primaryKey}); + + return SUCCESS(response); + } + + /// + /// 添加{FileName} + /// + /// + [HttpPost] + [ActionPermissionFilter(Permission = "{Permission}:add")] + [Log(Title = "{FileName}添加", BusinessType = BusinessType.INSERT)] + public IActionResult Create([FromBody] {ModelName}Dto parm) + { + if (parm == null) + { + throw new CustomException("请求参数错误"); + } + //从 Dto 映射到 实体 + var addModel = parm.Adapt<{ModelName}>().ToCreate(); + //addModel.CreateID = User.Identity.Name; + + return SUCCESS(_{ServiceName}.Add(addModel)); + } + + /// + /// 更新{FileName} + /// + /// + [HttpPut] + [ActionPermissionFilter(Permission = "{Permission}:update")] + [Log(Title = "{FileName}修改", BusinessType = BusinessType.UPDATE)] + public IActionResult Update([FromBody] {ModelName}Dto parm) + { + if (parm == null) + { + throw new CustomException("请求实体不能为空"); + } + //从 Dto 映射到 实体 + var updateModel = parm.Adapt<{ModelName}>().ToCreate(); + //updateModel.CreateID = User.Identity.Name; + + var response = _{ServiceName}.Update(w => w.{primaryKey} == updateModel.{primaryKey}, it => new {ModelName}() + { + //TODO 字段映射 + {updateColumn} + }); + + return SUCCESS(response); + } + + /// + /// 删除{FileName} + /// + /// + [HttpDelete("{{primaryKey}}")] + [ActionPermissionFilter(Permission = "{Permission}:delete")] + [Log(Title = "{FileName}删除", BusinessType = BusinessType.DELETE)] + public IActionResult Delete({KeyTypeName} {primaryKey} = 0) + { + if ({primaryKey} <= 0) { return OutputJson(ApiResult.Error($"删除失败Id 不能为空")); } + + // 删除{FileName} + var response = _{ServiceName}.Delete({primaryKey}); + + return SUCCESS(response); + } + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Template/IServiceTemplate.txt b/ZR.Admin.WebApi/Template/IServiceTemplate.txt new file mode 100644 index 0000000..8e3692b --- /dev/null +++ b/ZR.Admin.WebApi/Template/IServiceTemplate.txt @@ -0,0 +1,12 @@ +using System; +using {ModelsNamespace}.Models; + +namespace {IServicsNamespace}.Business +{ + /// + /// 定义{TableNameDesc}服务接口 + /// + public interface I{ModelTypeName}Service: IBaseService<{ModelTypeName}> + { + } +} diff --git a/ZR.Admin.WebApi/Template/InputDtoTemplate.txt b/ZR.Admin.WebApi/Template/InputDtoTemplate.txt new file mode 100644 index 0000000..656cdad --- /dev/null +++ b/ZR.Admin.WebApi/Template/InputDtoTemplate.txt @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using {ModelsNamespace}.Dto; +using {ModelsNamespace}.Models; + +namespace {DtosNamespace}.Dto +{ + /// + /// {TableNameDesc}输入对象模型 + /// + public class {ModelTypeName}Dto + { +{PropertyName} + } + + public class {ModelTypeName}QueryDto: PagerInfo + { + public DateTime? BeginTime { get; set; } + public DateTime? EndTime { get; set; } + } +} diff --git a/ZR.Admin.WebApi/Template/ModelTemplate.txt b/ZR.Admin.WebApi/Template/ModelTemplate.txt new file mode 100644 index 0000000..7d9a00a --- /dev/null +++ b/ZR.Admin.WebApi/Template/ModelTemplate.txt @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace {ModelsNamespace}.Models +{ + /// + /// {TableNameDesc},数据实体对象 + /// + [SqlSugar.SugarTable("{TableName}")] + public class {ModelTypeName} + { +{PropertyName} + } +} diff --git a/ZR.Admin.WebApi/Template/RepositoryTemplate.txt b/ZR.Admin.WebApi/Template/RepositoryTemplate.txt new file mode 100644 index 0000000..e39f922 --- /dev/null +++ b/ZR.Admin.WebApi/Template/RepositoryTemplate.txt @@ -0,0 +1,25 @@ +using System; +using Infrastructure.Attribute; +using {RepositoriesNamespace}.System; +using {ModelsNamespace}.Models; + +namespace {RepositoriesNamespace} +{ + /// + /// 代码生成器生成 + /// {TableNameDesc}仓储接口的实现 + /// + [AppService(ServiceLifetime = LifeTime.Transient)] + public class {ModelTypeName}Repository : BaseRepository + { + public {ModelTypeName}Repository() + { + } + + #region 业务逻辑代码 + + + + #endregion + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Template/ServiceTemplate.txt b/ZR.Admin.WebApi/Template/ServiceTemplate.txt new file mode 100644 index 0000000..1c88cf6 --- /dev/null +++ b/ZR.Admin.WebApi/Template/ServiceTemplate.txt @@ -0,0 +1,32 @@ +using Infrastructure; +using Infrastructure.Attribute; +using Infrastructure.Extensions; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ZR.Common; +using {ModelsNamespace}.Models; +using {IRepositoriesNamespace}; +using {ServicesNamespace}.IService; + +namespace {ServicesNamespace}.Business +{ + /// + /// 代码生成器生成 + /// + [AppService(ServiceType = typeof(I{ModelTypeName}Service), ServiceLifetime = LifeTime.Transient)] + public class {ModelTypeName}Service: BaseService<{ModelTypeName}>, I{ModelTypeName}Service + { + private readonly {ModelTypeName}Repository _repository; + public {ModelTypeName}Service({ModelTypeName}Repository repository) + { + _repository = repository; + } + + #region 业务逻辑代码 + + #endregion + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Template/VueJsTemplate.txt b/ZR.Admin.WebApi/Template/VueJsTemplate.txt new file mode 100644 index 0000000..719dfc7 --- /dev/null +++ b/ZR.Admin.WebApi/Template/VueJsTemplate.txt @@ -0,0 +1,59 @@ +import request from '@/utils/request' + +/** + * {ModelTypeDesc}分页查询 + * @param {查询条件} data + */ +export function list{ModelTypeName}(data) { + return request({ + url: 'bus/{ModelTypeName}/list', + method: 'get', + params: data, + }) +} + +/** + * 新增{ModelTypeDesc} + * @param data + */ +export function add{ModelTypeName}(data) { + return request({ + url: '/bus/{ModelTypeName}', + method: 'post', + data: data, + }) +} + +/** + * 修改{ModelTypeDesc} + * @param data + */ +export function update{ModelTypeName}(data) { + return request({ + url: '/bus/{ModelTypeName}', + method: 'PUT', + data: data, + }) +} + +/** + * 获取{ModelTypeDesc}详情 + * @param {Id} {ModelTypeDesc}Id + */ +export function get{ModelTypeName}(id) { + return request({ + url: '/bus/{ModelTypeName}/' + id, + method: 'get' + }) +} + +/** + * 删除 + * @param {主键} pid + */ +export function del{ModelTypeName}(pid) { + return request({ + url: '/bus/{ModelTypeName}/' + pid, + method: 'delete' + }) +} diff --git a/ZR.Admin.WebApi/Template/VueTemplate.txt b/ZR.Admin.WebApi/Template/VueTemplate.txt new file mode 100644 index 0000000..ac347d3 --- /dev/null +++ b/ZR.Admin.WebApi/Template/VueTemplate.txt @@ -0,0 +1,235 @@ + + + diff --git a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj index 9f82d37..cbbf3ed 100644 --- a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj +++ b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj @@ -32,6 +32,7 @@ + @@ -56,6 +57,30 @@ TextTemplatingFileGenerator Controller.cs + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + @@ -63,6 +88,16 @@ + + + + Always + + + Always + + + diff --git a/ZR.Admin.WebApi/appsettings.Development.json b/ZR.Admin.WebApi/appsettings.Development.json index 8d64c6d..61f44c9 100644 --- a/ZR.Admin.WebApi/appsettings.Development.json +++ b/ZR.Admin.WebApi/appsettings.Development.json @@ -6,9 +6,9 @@ "Microsoft.Hosting.Lifetime": "Information" } }, - "appName": "ZR Admin System", "ConnectionStrings": { - "Conn_Admin": "server=127.0.0.1;database=admin;user=zr;pwd=abc" + "Conn_Admin": "server=127.0.0.1;user=zr;pwd=abc;database=admin", + "ConnDynamic": "server=127.0.0.1;user=zr;pwd=abc;database={database}"//ʹ }, "urls": "http://localhost:8888", //url "sysConfig": { @@ -18,6 +18,7 @@ "DemoMode": false, //Ƿʾģʽ "DbKey": "", "DbType": 0, //MySql = 0, SqlServer = 1, Sqlite = 2, Oracle = 3, PostgreSQL = 4, + "CodeGenDbType": 0,//ݿ "Upload": { "UploadDirectory": "/", "UploadUrl": "http://localhost:8888" diff --git a/ZR.Admin.WebApi/appsettings.Production.json b/ZR.Admin.WebApi/appsettings.Production.json index 68ffe8e..8983e0f 100644 --- a/ZR.Admin.WebApi/appsettings.Production.json +++ b/ZR.Admin.WebApi/appsettings.Production.json @@ -5,26 +5,5 @@ "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } - }, - "appName": "ZR Admin system", - "ConnectionStrings": { - "Conn_Admin": "server=127.0.0.1;database=admin;user=zr;pwd=abc" - }, - "urls": "http://localhost:8888", - "sysConfig": { - "DBCommandTimeout": 10, - "cors": "http://localhost:8887" - }, - "DemoMode": false, //Ƿʾģʽ - "DbKey": "", - "DbType": 0, //MySql = 0, SqlServer = 1, Sqlite = 2, Oracle = 3, PostgreSQL = 4, - "Upload": { - "UploadDirectory": "/", - "UploadUrl": "http://localhost:8888" - }, - "ALYUN_OCS": { - "REGIONID": "cn-hangzhou", - "KEY": "XX", - "SECRET": "XX" } } diff --git a/ZR.CodeGenerator/CodeGenerateOption.cs b/ZR.CodeGenerator/CodeGenerateOption.cs new file mode 100644 index 0000000..abb237f --- /dev/null +++ b/ZR.CodeGenerator/CodeGenerateOption.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZR.CodeGenerator +{ + public class CodeGenerateOption + { + /// + /// 项目命名空间 + /// + public string BaseNamespace { get; set; } + /// + /// 数据实体命名空间 + /// + public string ModelsNamespace { get; set; } + /// + /// 输入输出数据实体名称空间 + /// + public string DtosNamespace { get; set; } + /// + /// 仓储接口命名空间 + /// + public string IRepositoriesNamespace { get; set; } + /// + /// 仓储实现名称空间 + /// + public string RepositoriesNamespace { get; set; } + /// + /// 服务接口命名空间 + /// + public string IServicsNamespace { get; set; } + /// + /// 服务接口实现命名空间 + /// + public string ServicesNamespace { get; set; } + + /// + /// Api控制器命名空间 + /// + public string ApiControllerNamespace { get; set; } + + /// + /// 去掉的表头字符 + /// + public string ReplaceTableNameStr { get; set; } + /// + /// 要生数据的表,用“,”分割 + /// + public string TableList { get; set; } + } +} diff --git a/ZR.CodeGenerator/CodeGenerateTemplate.cs b/ZR.CodeGenerator/CodeGenerateTemplate.cs new file mode 100644 index 0000000..e8c1796 --- /dev/null +++ b/ZR.CodeGenerator/CodeGenerateTemplate.cs @@ -0,0 +1,152 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZR.CodeGenerator.CodeGenerator; + +namespace ZR.CodeGenerator +{ + public class CodeGenerateTemplate + { + #region Template + + public static string GetVueJsMethod(DbColumnInfo dbColumnInfo) + { + string columnName = CodeGeneratorTool.FirstLowerCase(dbColumnInfo.DbColumnName); + string js = ""; + if (CodeGeneratorTool.imageFiled.Any(f => columnName.Contains(f))) + { + js += $"handleUpload{columnName}Success(res, file) {{\n"; + js += $" this.form.{columnName} = URL.createObjectURL(file.raw);\n"; + js += " // this.$refs.upload.clearFiles();\n"; + js += "},\n"; + } + return js; + } + + //rules + public static string GetFormRules(DbColumnInfo dbFieldInfo) + { + string vueViewEditFromRuleContent = ""; + //Rule 规则验证 + if (!dbFieldInfo.IsNullable && !dbFieldInfo.IsIdentity) + { + vueViewEditFromRuleContent += $" {dbFieldInfo.DbColumnName}: [\n"; + vueViewEditFromRuleContent += $" {{ required: true, message:\"请输入{dbFieldInfo.ColumnDescription}\", trigger: \"blur\"}},\n"; + //vueViewEditFromRuleContent += " { min: 2, max: 50, message: \"长度在 2 到 50 个字符\", trigger:\"blur\" }\n"; + vueViewEditFromRuleContent += " ],\n"; + } + + return vueViewEditFromRuleContent; + } + + //model 属性 + public static string GetModelTemplate(DbColumnInfo dbFieldInfo) + { + string columnName = dbFieldInfo.DbColumnName.Substring(0, 1).ToUpper() + dbFieldInfo.DbColumnName[1..]; + var modelcontent = ""; + modelcontent += " /// \n"; + modelcontent += $" /// 描述 :{dbFieldInfo.ColumnDescription}\n"; + modelcontent += $" /// 空值 :{dbFieldInfo.IsNullable}\n"; + modelcontent += $" /// 默认 :{dbFieldInfo.DefaultValue}\n"; + modelcontent += " /// \n"; + if (dbFieldInfo.IsIdentity || dbFieldInfo.IsPrimarykey) + { + modelcontent += $" [SqlSugar.SugarColumn(IsPrimaryKey = {dbFieldInfo.IsPrimarykey.ToString().ToLower()}, IsIdentity = {dbFieldInfo.IsIdentity.ToString().ToLower()})]\n"; + } + modelcontent += $" public {TableMappingHelper.GetPropertyDatatype(dbFieldInfo.DataType)} {columnName} {{ get; set; }}\n\r"; + return modelcontent; + } + //DTO model + public static string GetDtoContent(DbColumnInfo dbFieldInfo) + { + string columnName = dbFieldInfo.DbColumnName.Substring(0, 1).ToUpper() + dbFieldInfo.DbColumnName[1..]; + string InputDtoContent = ""; + InputDtoContent += $" public {TableMappingHelper.GetPropertyDatatype(dbFieldInfo.DataType)} {columnName} {{ get; set; }}\n\r"; + + return InputDtoContent; + } + + //form-item + public static string GetVueViewFormContent(DbColumnInfo dbFieldInfo) + { + string columnName = CodeGeneratorTool.FirstLowerCase(dbFieldInfo.DbColumnName); + string labelName = CodeGeneratorTool.GetLabelName(dbFieldInfo.ColumnDescription, columnName); + string vueViewFromContent = ""; + string labelDisabled = dbFieldInfo.IsIdentity ? ":disabled=\"true\"" : ""; + string placeHolder = dbFieldInfo.IsIdentity ? "" : $"请输入{CodeGeneratorTool.GetLabelName(dbFieldInfo.ColumnDescription, columnName)}"; + + if (dbFieldInfo.DataType == "datetime") + { + //时间 + vueViewFromContent += $" \n"; + vueViewFromContent += $" \n"; + vueViewFromContent += " \n"; + } + else if (CodeGeneratorTool.imageFiled.Any(f => columnName.Contains(f))) + { + //图片 + vueViewFromContent += $" \n"; + vueViewFromContent += $" \n"; + vueViewFromContent += $" \n"; + vueViewFromContent += " \n"; + vueViewFromContent += " \n"; + vueViewFromContent += $" \n"; + vueViewFromContent += " \n"; + } + else if (CodeGeneratorTool.radioFiled.Any(f => columnName.Contains(f)) && (dbFieldInfo.DataType == "bool" || dbFieldInfo.DataType == "tinyint" || dbFieldInfo.DataType == "int")) + { + vueViewFromContent += $" "; + vueViewFromContent += $" \n"; + vueViewFromContent += " {{dict.dictLabel}}\n"; + vueViewFromContent += " \n"; + vueViewFromContent += " \n"; + } + else + { + vueViewFromContent += $" \n"; + vueViewFromContent += $" \n"; + vueViewFromContent += " \n"; + } + + return vueViewFromContent; + } + + //table-column + public static string GetTableColumn(DbColumnInfo dbFieldInfo) + { + string columnName = CodeGeneratorTool.FirstLowerCase(dbFieldInfo.DbColumnName); + string label = CodeGeneratorTool.GetLabelName(dbFieldInfo.ColumnDescription, columnName); + string vueViewListContent = ""; + string showToolTip = dbFieldInfo.DataType.Contains("varchar") ? ":show-overflow-tooltip=\"true\"" : ""; + + if (CodeGeneratorTool.imageFiled.Any(f => columnName.ToLower().Contains(f))) + { + vueViewListContent += $" \n"; + vueViewListContent += " \n"; + vueViewListContent += " \n"; + } + else if (dbFieldInfo.DataType == "bool" || dbFieldInfo.DataType == "tinyint") + { + vueViewListContent += $" \n"; + vueViewListContent += " \n"; + vueViewListContent += " \n"; + } + else + { + //table-column + vueViewListContent += $" \n"; + } + return vueViewListContent; + } + #endregion + + } +} diff --git a/ZR.CodeGenerator/CodeGeneratorTool.cs b/ZR.CodeGenerator/CodeGeneratorTool.cs new file mode 100644 index 0000000..8667eab --- /dev/null +++ b/ZR.CodeGenerator/CodeGeneratorTool.cs @@ -0,0 +1,518 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using ZR.CodeGenerator.Model; +using ZR.CodeGenerator.Service; + +namespace ZR.CodeGenerator +{ + /// + /// 代码生成器。 + /// + /// 根据指定的实体域名空间生成Repositories和Services层的基础代码文件。 + /// + /// + public class CodeGeneratorTool + { + /// + /// 代码生成器配置 + /// + private static CodeGenerateOption _option = new CodeGenerateOption(); + /// + /// InputDto输入实体是不包含字段 + /// + public static readonly string[] inputDtoNoField = new string[] { "DeleteMark", "CreateTime", "updateTime", "addtime" }; + public static readonly string[] imageFiled = new string[] { "icon", "img", "image", "url", "pic", "photo" }; + public static readonly string[] selectFiled = new string[] { "status", "type", "state", "sex", "gender" }; + public static readonly string[] radioFiled = new string[] { "status", "state", "isShow", "isHidden", "ishide" }; + + /// + /// 代码生成器入口方法 + /// + /// + /// + public static void Generate(DbTableInfo dbTableInfo, GenerateDto dto) + { + //_option.BaseNamespace = baseNamespace; + //_option.TableList = listTable; + _option.ReplaceTableNameStr = dto.replaceTableNameStr; + _option.DtosNamespace = "ZR.Model"; + _option.ModelsNamespace = "ZR.Model"; + _option.RepositoriesNamespace = "ZR.Repository"; + _option.IRepositoriesNamespace = "ZR.Repository"; + _option.IServicsNamespace = "ZR.Service"; + _option.ServicesNamespace = "ZR.Service"; + _option.ApiControllerNamespace = "ZR.Admin.WebApi"; + + CodeGeneraterService codeGeneraterService = new CodeGeneraterService(); + + List listField = codeGeneraterService.GetColumnInfo(dto.dbName, dbTableInfo.Name); + GenerateSingle(listField, dbTableInfo, dto); + + //GenerateDtoProfile(_option.ModelsNamespace, profileContent, ifExsitedCovered); + } + + /// + /// 单表生成代码 + /// + /// 表字段集合 + /// 表信息 + /// 如果目标文件存在,是否覆盖。默认为false + public static void GenerateSingle(List listField, DbTableInfo tableInfo, GenerateDto dto) + { + bool ifExsitedCovered = dto.coverd; + var modelTypeName = GetModelClassName(tableInfo.Name);//表名对应C# 实体类名 + var modelTypeDesc = tableInfo.Description;//表描述 + var primaryKey = "id";//主键 + + string keyTypeName = "int";//主键数据类型 + string modelContent = "";//数据库模型字段 + string InputDtoContent = "";//输入模型 + //string outputDtoContent = "";//输出模型 + string updateColumn = "";//修改数据映射字段 + string vueViewListContent = string.Empty;//Vue列表输出内容 + string vueViewFormContent = string.Empty;//Vue表单输出内容 + string vueViewEditFromContent = string.Empty;//Vue变量输出内容 + string vueViewEditFromBindContent = string.Empty;//Vue显示初始化输出内容 + string vueViewSaveBindContent = string.Empty;//Vue保存时输出内容 + string vueViewEditFromRuleContent = string.Empty;//Vue数据校验 + string vueJsMethod = string.Empty;//Vue js自定义方法 + + foreach (DbColumnInfo dbFieldInfo in listField) + { + string columnName = FirstLowerCase(dbFieldInfo.DbColumnName); + + if (dbFieldInfo.DataType == "bool" || dbFieldInfo.DataType == "tinyint") + { + vueViewEditFromContent += $" {columnName}: 'true',\n"; + //vueViewEditFromBindContent += $" this.form.{columnName} = res.data.{0}+''\n"; + } + else + { + vueViewEditFromContent += $" {columnName}: undefined,\n"; + //vueViewEditFromBindContent += $" {columnName}: row.{columnName},\n"; + } + //vueViewSaveBindContent += string.Format(" '{0}':this.editFrom.{0},\n", columnName); + //主键 + if (dbFieldInfo.IsIdentity || dbFieldInfo.IsPrimarykey) + { + primaryKey = columnName.Substring(0, 1).ToUpper() + columnName[1..]; + keyTypeName = dbFieldInfo.DataType; + } + else + { + var tempColumnName = columnName.Substring(0, 1).ToUpper() + columnName[1..]; + updateColumn += $" {tempColumnName} = parm.{tempColumnName},\n"; + } + + dbFieldInfo.DbColumnName = columnName; + modelContent += CodeGenerateTemplate.GetModelTemplate(dbFieldInfo); + vueViewFormContent += CodeGenerateTemplate.GetVueViewFormContent(dbFieldInfo); + vueJsMethod += CodeGenerateTemplate.GetVueJsMethod(dbFieldInfo); + vueViewListContent += CodeGenerateTemplate.GetTableColumn(dbFieldInfo); + vueViewEditFromRuleContent += CodeGenerateTemplate.GetFormRules(dbFieldInfo); + InputDtoContent += CodeGenerateTemplate.GetDtoContent(dbFieldInfo); + } + if (dto.genFiles.Contains(1)) + { + GenerateModels(_option.ModelsNamespace, modelTypeName, tableInfo.Name, modelContent, modelTypeDesc, keyTypeName, ifExsitedCovered); + } + if (dto.genFiles.Contains(2)) + { + GenerateInputDto(_option.ModelsNamespace, modelTypeName, modelTypeDesc, InputDtoContent, keyTypeName, ifExsitedCovered); + } + if (dto.genFiles.Contains(3)) + { + GenerateRepository(modelTypeName, modelTypeDesc, tableInfo.Name, keyTypeName, ifExsitedCovered); + } + if (dto.genFiles.Contains(4)) + { + GenerateIService(_option.ModelsNamespace, modelTypeName, modelTypeDesc, keyTypeName, ifExsitedCovered); + GenerateService(_option.ModelsNamespace, modelTypeName, modelTypeDesc, keyTypeName, ifExsitedCovered); + } + if (dto.genFiles.Contains(5)) + { + GenerateControllers(modelTypeName, primaryKey, modelTypeDesc, keyTypeName, updateColumn, ifExsitedCovered); + } + if (dto.genFiles.Contains(6)) + { + GenerateVueViews(modelTypeName, primaryKey, modelTypeDesc, vueViewListContent, vueViewFormContent, vueViewEditFromContent, vueViewEditFromBindContent, vueViewSaveBindContent, vueViewEditFromRuleContent, vueJsMethod, ifExsitedCovered); + } + //GenerateIRepository(modelTypeName, modelTypeDesc, keyTypeName, ifExsitedCovered); + //GenerateOutputDto(modelTypeName, modelTypeDesc, outputDtocontent, ifExsitedCovered); + } + + + #region 生成Model + + /// + /// 生成Models文件 + /// + /// 命名空间 + /// 类名 + /// 表名称 + /// 表描述 + /// 数据库表实体内容 + /// 主键数据类型 + /// 如果目标文件存在,是否覆盖。默认为false + private static Tuple GenerateModels(string modelsNamespace, string modelTypeName, string tableName, string modelContent, string modelTypeDesc, string keyTypeName, bool ifExsitedCovered = false) + { + var parentPath = ".."; + //../ZR.Model + var servicesPath = parentPath + "\\" + modelsNamespace + "\\Models\\"; + if (!Directory.Exists(servicesPath)) + { + Directory.CreateDirectory(servicesPath); + } + // ../ZR.Model/Models/User.cs + var fullPath = servicesPath + modelTypeName + ".cs"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); + var content = ReadTemplate("ModelTemplate.txt"); + content = content + .Replace("{ModelsNamespace}", modelsNamespace) + .Replace("{ModelTypeName}", modelTypeName) + .Replace("{TableNameDesc}", modelTypeDesc) + .Replace("{KeyTypeName}", keyTypeName) + .Replace("{PropertyName}", modelContent) + .Replace("{TableName}", tableName); + WriteAndSave(fullPath, content); + return Tuple.Create(fullPath, content); + } + + + /// + /// 生成InputDto文件 + /// + /// + /// + /// + /// + /// + /// 如果目标文件存在,是否覆盖。默认为false + private static Tuple GenerateInputDto(string modelsNamespace, string modelTypeName, string modelTypeDesc, string modelContent, string keyTypeName, bool ifExsitedCovered = false) + { + var parentPath = ".."; + var servicesPath = parentPath + "\\" + modelsNamespace + "\\Dto\\"; + if (!Directory.Exists(servicesPath)) + { + Directory.CreateDirectory(servicesPath); + } + // ../ZR.Model/Dto/User.cs + var fullPath = servicesPath + modelTypeName + "Dto.cs"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); ; + var content = ReadTemplate("InputDtoTemplate.txt"); + content = content + .Replace("{DtosNamespace}", _option.DtosNamespace) + .Replace("{ModelsNamespace}", modelsNamespace) + .Replace("{TableNameDesc}", modelTypeDesc) + .Replace("{KeyTypeName}", keyTypeName) + .Replace("{PropertyName}", modelContent) + .Replace("{ModelTypeName}", modelTypeName); + WriteAndSave(fullPath, content); + return Tuple.Create(fullPath, content); + } + #endregion + + #region 生成Repository + + /// + /// 生成Repository层代码文件 + /// + /// + /// + /// 表名 + /// + /// 如果目标文件存在,是否覆盖。默认为false + private static Tuple GenerateRepository(string modelTypeName, string modelTypeDesc, string tableName, string keyTypeName, bool ifExsitedCovered = false) + { + var parentPath = ".."; + var repositoryPath = parentPath + "\\" + _option.RepositoriesNamespace + "\\Repositories\\"; + if (!Directory.Exists(repositoryPath)) + { + Directory.CreateDirectory(repositoryPath); + } + var fullPath = repositoryPath + "\\" + modelTypeName + "Repository.cs"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); + var content = ReadTemplate("RepositoryTemplate.txt"); + content = content.Replace("{ModelsNamespace}", _option.ModelsNamespace) + //.Replace("{IRepositoriesNamespace}", _option.IRepositoriesNamespace) + .Replace("{RepositoriesNamespace}", _option.RepositoriesNamespace) + .Replace("{ModelTypeName}", modelTypeName) + .Replace("{TableNameDesc}", modelTypeDesc) + .Replace("{TableName}", tableName) + .Replace("{KeyTypeName}", keyTypeName); + WriteAndSave(fullPath, content); + return Tuple.Create(fullPath, content); + } + + #endregion + + #region 生成Service + /// + /// 生成IService文件 + /// + /// + /// + /// + /// + /// 如果目标文件存在,是否覆盖。默认为false + private static Tuple GenerateIService(string modelsNamespace, string modelTypeName, string modelTypeDesc, string keyTypeName, bool ifExsitedCovered = false) + { + var parentPath = ".."; + var iServicesPath = parentPath + "\\" + _option.IServicsNamespace + "\\Business\\IBusService\\"; + if (!Directory.Exists(iServicesPath)) + { + Directory.CreateDirectory(iServicesPath); + } + var fullPath = $"{iServicesPath}\\I{modelTypeName}Service.cs"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); + var content = ReadTemplate("IServiceTemplate.txt"); + content = content.Replace("{ModelsNamespace}", modelsNamespace) + .Replace("{TableNameDesc}", modelTypeDesc) + .Replace("{DtosNamespace}", _option.DtosNamespace) + .Replace("{IServicsNamespace}", _option.IServicsNamespace) + .Replace("{RepositoriesNamespace}", _option.RepositoriesNamespace) + .Replace("{ModelTypeName}", modelTypeName) + .Replace("{KeyTypeName}", keyTypeName); + WriteAndSave(fullPath, content); + return Tuple.Create(fullPath, content); + } + + /// + /// 生成Service文件 + /// + /// + /// + /// + /// + /// 如果目标文件存在,是否覆盖。默认为false + private static Tuple GenerateService(string modelsNamespace, string modelTypeName, string modelTypeDesc, string keyTypeName, bool ifExsitedCovered = false) + { + var parentPath = ".."; + var servicesPath = parentPath + "\\" + _option.ServicesNamespace + "\\Business\\"; + if (!Directory.Exists(servicesPath)) + { + Directory.CreateDirectory(servicesPath); + } + var fullPath = servicesPath + modelTypeName + "Service.cs"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); + var content = ReadTemplate("ServiceTemplate.txt"); + content = content + .Replace("{IRepositoriesNamespace}", _option.IRepositoriesNamespace) + .Replace("{DtosNamespace}", _option.DtosNamespace) + .Replace("{IServicsNamespace}", _option.IServicsNamespace) + .Replace("{TableNameDesc}", modelTypeDesc) + .Replace("{ModelsNamespace}", modelsNamespace) + .Replace("{ServicesNamespace}", _option.ServicesNamespace) + .Replace("{ModelTypeName}", modelTypeName) + .Replace("{KeyTypeName}", keyTypeName); + WriteAndSave(fullPath, content); + return Tuple.Create(fullPath, content); + } + + #endregion + + #region 生成Controller + /// + /// 生成控制器ApiControllers文件 + /// + /// 实体类型名称 + /// 主键 + /// 实体描述 + /// + /// 如果目标文件存在,是否覆盖。默认为false + private static Tuple GenerateControllers(string modelTypeName, string primaryKey, string modelTypeDesc, string keyTypeName, string updateColumn, bool ifExsitedCovered = false) + { + var parentPath = ".."; + var servicesPath = parentPath + "\\" + _option.ApiControllerNamespace + "\\Controllers\\business\\"; + if (!Directory.Exists(servicesPath)) + { + Directory.CreateDirectory(servicesPath); + } + var fullPath = servicesPath + modelTypeName + "Controller.cs"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); + var content = ReadTemplate("ControllersTemplate.txt"); + content = content + //.Replace("{DtosNamespace}", _option.DtosNamespace) + .Replace("{ControllerName}", modelTypeName) + .Replace("{ModelsNamespace}", _option.ModelsNamespace) + .Replace("{FileName}", modelTypeDesc) + .Replace("{ServiceName}", modelTypeName + "Service") + .Replace("{ModelName}", modelTypeName) + .Replace("{Permission}", modelTypeName.ToLower()) + .Replace("{primaryKey}", primaryKey) + .Replace("{updateColumn}", updateColumn) + .Replace("{KeyTypeName}", keyTypeName); + WriteAndSave(fullPath, content); + return Tuple.Create(fullPath, content); + } + #endregion + + #region 生成Vue页面 + /// + /// 生成Vue页面 + /// + /// 类名 + /// 表/类描述 + /// + /// + /// + /// + /// + /// + /// 如果目标文件存在,是否覆盖。默认为false + private static Tuple GenerateVueViews(string modelTypeName, string primaryKey, string modelTypeDesc, string vueViewListContent, string vueViewFromContent, string vueViewEditFromContent, string vueViewEditFromBindContent, string vueViewSaveBindContent, string vueViewEditFromRuleContent, string vueJsMethod, bool ifExsitedCovered = false) + { + //var parentPath = "..\\CodeGenerate";//若要生成到项目中将路径改成 “..\\ZR.Vue\\src” + var parentPath = "..\\ZR.Vue\\src"; + var servicesPath = parentPath + "\\views\\" + FirstLowerCase(modelTypeName); + if (!Directory.Exists(servicesPath)) + { + Directory.CreateDirectory(servicesPath); + } + var fullPath = servicesPath + "\\" + "index.vue"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); ; + var content = ReadTemplate("VueTemplate.txt"); + content = content + .Replace("{fileClassName}", FirstLowerCase(modelTypeName)) + .Replace("{VueViewListContent}", vueViewListContent)//查询 table列 + .Replace("{VueViewFormContent}", vueViewFromContent)//添加、修改表单 + .Replace("{ModelTypeName}", modelTypeName) + .Replace("{Permission}", modelTypeName.ToLower()) + .Replace("{VueViewEditFormContent}", vueViewEditFromContent) + .Replace("{vueJsMethod}", vueJsMethod) + //.Replace("{VueViewEditFromBindContent}", vueViewEditFromBindContent) + //.Replace("{VueViewSaveBindContent}", vueViewSaveBindContent) + .Replace("{primaryKey}", FirstLowerCase(primaryKey)) + .Replace("{VueViewEditFormRuleContent}", vueViewEditFromRuleContent);//添加、修改表单验证规则 + WriteAndSave(fullPath, content); + + //api js + servicesPath = parentPath + "\\api\\"; + Directory.CreateDirectory(servicesPath); + fullPath = servicesPath + "\\" + FirstLowerCase(modelTypeName) + ".js"; + Console.WriteLine(fullPath); + if (File.Exists(fullPath) && !ifExsitedCovered) + return Tuple.Create(fullPath, ""); + content = ReadTemplate("VueJsTemplate.txt"); + content = content + .Replace("{ModelTypeName}", modelTypeName) + .Replace("{ModelTypeDesc}", modelTypeDesc); + //.Replace("{fileClassName}", fileClassName) + WriteAndSave(fullPath, content); + return Tuple.Create(fullPath, content); + } + + #endregion + + #region 帮助方法 + + /// + /// 如果有前缀替换将前缀替换成空,替换下划线"_"为空再将首字母大写 + /// + /// + /// + public static string GetModelClassName(string modelTypeName) + { + if (!string.IsNullOrEmpty(_option.ReplaceTableNameStr)) + { + modelTypeName = modelTypeName.Replace(_option.ReplaceTableNameStr.ToString(), ""); + } + modelTypeName = modelTypeName.Replace("_", ""); + modelTypeName = modelTypeName.Substring(0, 1).ToUpper() + modelTypeName[1..]; + return modelTypeName; + } + /// + /// 首字母转小写,输出前端 + /// + /// + /// + public static string FirstLowerCase(string str) + { + return string.IsNullOrEmpty(str) ? str : str.Substring(0, 1).ToLower() + str[1..]; + } + + /// + /// 获取前端标签名 + /// + /// + /// + /// + public static string GetLabelName(string columnDescription, string columnName) + { + return string.IsNullOrEmpty(columnDescription) ? columnName : columnDescription; + } + /// + /// 从代码模板中读取内容 + /// + /// 模板名称,应包括文件扩展名称。比如:template.txt + /// + private static string ReadTemplate(string templateName) + { + var path = AppDomain.CurrentDomain.BaseDirectory; + string fullName = $"{path}\\Template\\{templateName}"; + string temp = fullName; + string str = ""; + if (!File.Exists(temp)) + { + return str; + } + StreamReader sr = null; + try + { + sr = new StreamReader(temp); + str = sr.ReadToEnd(); // 读取文件 + } + catch { } + sr?.Close(); + sr?.Dispose(); + return str; + + } + + /// + /// 写文件 + /// + /// + /// + private static void WriteAndSave(string fileName, string content) + { + try + { + //实例化一个文件流--->与写入文件相关联 + using var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); + //实例化一个StreamWriter-->与fs相关联 + using var sw = new StreamWriter(fs); + //开始写入 + sw.Write(content); + //清空缓冲区 + sw.Flush(); + //关闭流 + sw.Close(); + fs.Close(); + } + catch (Exception ex) + { + Console.WriteLine("写入文件出错了:" + ex.Message); + } + } + + #endregion + } +} diff --git a/ZR.CodeGenerator/DbProvider.cs b/ZR.CodeGenerator/DbProvider.cs new file mode 100644 index 0000000..56525f3 --- /dev/null +++ b/ZR.CodeGenerator/DbProvider.cs @@ -0,0 +1,43 @@ +using Infrastructure; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZR.CodeGenerator +{ + public class DbProvider + { + protected static SqlSugarScope CodeDb; + + /// + /// 获取动态连接字符串 + /// + /// 数据库名 + /// + public SqlSugarScope GetSugarDbContext(string dbName = "") + { + string connStr = ConfigUtils.Instance.GetConnectionStrings(OptionsSetting.Conn).Replace("{database}", dbName); + int dbType = ConfigUtils.Instance.GetAppConfig(OptionsSetting.CodeGenDbType, 0); + if (string.IsNullOrEmpty(dbName)) + { + connStr = ConfigUtils.Instance.GetConnectionStrings(OptionsSetting.ConnAdmin); + dbType = ConfigUtils.Instance.GetAppConfig(OptionsSetting.DbType, 0); + } + var db = new SqlSugarScope(new List() + { + new ConnectionConfig(){ + ConnectionString = connStr, + DbType = (DbType)dbType, + IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样 + InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息 + }, + }); + + CodeDb = db; + return db; + } + } +} diff --git a/ZR.CodeGenerator/Model/GenerateDto.cs b/ZR.CodeGenerator/Model/GenerateDto.cs new file mode 100644 index 0000000..60399fc --- /dev/null +++ b/ZR.CodeGenerator/Model/GenerateDto.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZR.CodeGenerator.Model +{ + public class GenerateDto + { + public string[] queryColumn { get; set; } + /// + /// + /// + public string dbName { get; set; } + /// + /// 项目命名空间 + /// + public string baseSpace { get; set; } + /// + /// 要生成代码的表 + /// + public string tableName { get; set; } + /// + /// 要删除表名的字符串用 + /// + public string replaceTableNameStr { get; set; } + /// + /// 要生成的文件 + /// + public int[] genFiles { get; set; } + public bool coverd { get; set; } = true; + } +} diff --git a/ZR.CodeGenerator/Service/CodeGeneraterService.cs b/ZR.CodeGenerator/Service/CodeGeneraterService.cs new file mode 100644 index 0000000..f22a3bf --- /dev/null +++ b/ZR.CodeGenerator/Service/CodeGeneraterService.cs @@ -0,0 +1,52 @@ +using SqlSugar; +using System.Collections.Generic; +using System.Linq; +using ZR.Model; + +namespace ZR.CodeGenerator.Service +{ + public class CodeGeneraterService : DbProvider + { + /// + /// 获取所有数据库名 + /// + /// + public List GetAllDataBases() + { + var db = GetSugarDbContext(); + var templist = db.DbMaintenance.GetDataBaseList(db.ScopedContext); + + return templist; + } + + /// + /// 获取所有表 + /// + /// + /// + /// + /// + public List GetAllTables(string dbName, string tableName, PagerInfo pager) + { + var tableList = GetSugarDbContext(dbName).DbMaintenance.GetTableInfoList(true); + if (!string.IsNullOrEmpty(tableName)) + { + tableList = tableList.Where(f => f.Name.ToLower().Contains(tableName.ToLower())).ToList(); + } + pager.TotalNum = tableList.Count; + return tableList.Skip(pager.PageSize * (pager.PageNum - 1)).Take(pager.PageSize).OrderBy(f => f.Name).ToList(); + } + + /// + /// 获取列信息 + /// + /// + /// + /// + public List GetColumnInfo(string dbName, string tableName) + { + return GetSugarDbContext(dbName).DbMaintenance.GetColumnInfosByTableName(tableName, true); + } + + } +} diff --git a/ZR.CodeGenerator/TableMappingHelper.cs b/ZR.CodeGenerator/TableMappingHelper.cs index e0c9daa..44f8e38 100644 --- a/ZR.CodeGenerator/TableMappingHelper.cs +++ b/ZR.CodeGenerator/TableMappingHelper.cs @@ -34,6 +34,8 @@ namespace ZR.CodeGenerator.CodeGenerator public static string GetClassNamePrefix(string tableName) { string[] arr = tableName.Split('_'); + if (arr.Length <= 0) return tableName; + StringBuilder sb = new StringBuilder(); for (int i = 1; i < arr.Length; i++) { diff --git a/ZR.CodeGenerator/ZR.CodeGenerator.csproj b/ZR.CodeGenerator/ZR.CodeGenerator.csproj index 948f805..cbcf969 100644 --- a/ZR.CodeGenerator/ZR.CodeGenerator.csproj +++ b/ZR.CodeGenerator/ZR.CodeGenerator.csproj @@ -11,8 +11,13 @@ - - + + + + + + PreserveNewest + diff --git a/ZR.Model/Models/README.txt b/ZR.Model/Models/README.txt new file mode 100644 index 0000000..39e9872 --- /dev/null +++ b/ZR.Model/Models/README.txt @@ -0,0 +1 @@ +此文件夹用于存放业务代码数据库实体类 \ No newline at end of file diff --git a/ZR.Model/System/SysMenu.cs b/ZR.Model/System/SysMenu.cs index 1af655c..36f53f7 100644 --- a/ZR.Model/System/SysMenu.cs +++ b/ZR.Model/System/SysMenu.cs @@ -13,7 +13,7 @@ namespace ZR.Model.System /// 菜单ID /// //[Key]//非自动增长主键时使用ExplicitKey - [SqlSugar.SugarColumn(IsPrimaryKey = true)] + [SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public long menuId { get; set; } /// /// 菜单名称 diff --git a/ZR.Repository/DbProvider/SugarDbContext.cs b/ZR.Repository/DbProvider/SugarDbContext.cs index 67ec657..68f7afe 100644 --- a/ZR.Repository/DbProvider/SugarDbContext.cs +++ b/ZR.Repository/DbProvider/SugarDbContext.cs @@ -27,6 +27,7 @@ namespace ZR.Repository.DbProvider { connStr = NETCore.Encrypt.EncryptProvider.DESDecrypt(connStr, dbKey); } + Db = new SqlSugarClient(new List() { new ConnectionConfig(){ @@ -41,6 +42,7 @@ namespace ZR.Repository.DbProvider //调式代码 用来打印SQL Db.Aop.OnLogExecuting = (sql, pars) => { + Console.BackgroundColor = ConsoleColor.Yellow; Console.WriteLine("【SQL语句】" + sql.ToLower() + "\r\n" + Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))); }; //出错打印日志 @@ -50,5 +52,21 @@ namespace ZR.Repository.DbProvider Console.WriteLine(); }; } + + public SqlSugarClient GetSugarDbContext(string dbName) + { + string connStr = ConfigUtils.Instance.GetConnectionStrings(OptionsSetting.Conn).Replace("{DbName}", dbName); + int dbType = ConfigUtils.Instance.GetAppConfig(OptionsSetting.DbType, 0); + + return new SqlSugarClient(new List() + { + new ConnectionConfig(){ + ConnectionString = connStr, + DbType = (DbType)dbType, + IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样 + InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息 + }, + }); + } } } diff --git a/ZR.Repository/System/SysUserRepository.cs b/ZR.Repository/System/SysUserRepository.cs index 03ab81c..754edcd 100644 --- a/ZR.Repository/System/SysUserRepository.cs +++ b/ZR.Repository/System/SysUserRepository.cs @@ -29,7 +29,7 @@ namespace ZR.Repository.System .WhereIF(!string.IsNullOrEmpty(user.UserName), it => it.UserName.Contains(user.UserName)) .WhereIF(!string.IsNullOrEmpty(user.Status), it => it.Status == user.Status) .WhereIF(user.BeginTime != DateTime.MinValue && user.BeginTime != null, it => it.Create_time >= user.BeginTime) - .WhereIF(user.EndTime != DateTime.MinValue && user.BeginTime != null, it => it.EndTime <= user.EndTime) + .WhereIF(user.EndTime != DateTime.MinValue && user.BeginTime != null, it => it.Create_time <= user.EndTime) .WhereIF(user.DeptId != 0, it => it.DeptId == user.DeptId) .OrderBy(it => it.UserId) .ToPageList(pager.PageNum, pager.PageSize, ref totalCount); diff --git a/ZR.Repository/ZR.Repository.csproj b/ZR.Repository/ZR.Repository.csproj index c4175f5..dd8fc0f 100644 --- a/ZR.Repository/ZR.Repository.csproj +++ b/ZR.Repository/ZR.Repository.csproj @@ -15,4 +15,8 @@ + + + + diff --git a/ZR.Service/IBaseService.cs b/ZR.Service/IBaseService.cs index 72959f0..e77d47b 100644 --- a/ZR.Service/IBaseService.cs +++ b/ZR.Service/IBaseService.cs @@ -3,8 +3,6 @@ using SqlSugar; using System; using System.Collections.Generic; using System.Linq.Expressions; -using System.Threading.Tasks; -using ZR.Model; namespace ZR.Service { @@ -138,7 +136,7 @@ namespace ZR.Service /// /// /// - PagedInfo GetPages(Expression> where, PagerInfo parm); + PagedInfo GetPages(Expression> where, Model.PagerInfo parm); /// /// 根据条件查询分页 @@ -148,7 +146,7 @@ namespace ZR.Service /// /// /// - PagedInfo GetPages(Expression> where, PagerInfo parm, Expression> order, string orderEnum = "Asc"); + PagedInfo GetPages(Expression> where, Model.PagerInfo parm, Expression> order, string orderEnum = "Asc"); /// /// 根据条件查询数据 diff --git a/ZR.Service/ZR.Service.csproj b/ZR.Service/ZR.Service.csproj index 6f3c4d0..a27cb43 100644 --- a/ZR.Service/ZR.Service.csproj +++ b/ZR.Service/ZR.Service.csproj @@ -9,4 +9,9 @@ + + + + + diff --git a/ZR.Vue/document/t4.tt b/ZR.Vue/document/t4.tt deleted file mode 100644 index e69de29..0000000 diff --git a/ZR.Vue/document/template.vue b/ZR.Vue/document/template.vue index 4f7996b..74895c2 100644 --- a/ZR.Vue/document/template.vue +++ b/ZR.Vue/document/template.vue @@ -2,9 +2,13 @@
+<<<<<<< HEAD +======= + +>>>>>>> db49575a0ded0eef5e8a68461da1448cdacb3d69 - + @@ -16,18 +20,18 @@ - + - + - 搜索 + 搜索 重置 @@ -44,13 +48,13 @@ 删除 - + + @@ -86,7 +90,7 @@ - + @@ -106,7 +110,7 @@ - {{dict.dictLabel}} + {{dict.dictLabel}} @@ -132,23 +136,23 @@ export default { name: "demo", data() { return { + labelWidth: "70px", // 遮罩层 loading: true, // 显示搜索条件 showSearch: true, // 查询参数 - queryParams: { - useridx: undefined, - name: undefined, - }, + queryParams: {}, // 弹出层标题 title: "", // 是否显示弹出层 open: false, // 表单参数 form: {}, + // 时间范围数组 + timeRange: [], // xxx下拉框 - options: [], + statusOptions: [], // 数据列表 dataList: [ { @@ -170,18 +174,30 @@ export default { // 表单校验 rules: { name: [{ required: true, message: "名称不能为空", trigger: "blur" }], - userId: [{ required: true, message: "id不能为空", trigger: "blur" }], + userId: [ + { + type: "number", + required: true, + message: "id不能为空,且不能为非数字", + trigger: "blur", + }, + ], }, }; }, mounted() { + // 列表数据查询 this.getList(); + // 下拉框绑定 + // this.getDicts("sys_normal_disable").then((response) => { + // this.statusOptions = response.data; + // }); }, methods: { // 查询数据 getList() { console.log(JSON.stringify(this.queryParams)); - // listXXXX().then(res => { + // listXXXX(this.addDateRange(this.queryParams, this.timeRange)).then(res => { // if (res.code == 200) { // this.dataList = res.data.result; // this.total = res.data.totalCount; @@ -195,7 +211,6 @@ export default { }, // 重置数据表单 reset() { - this.btnSubmitVisible = true; this.form = { Id: undefined, // TODO 其他列字段 @@ -204,7 +219,12 @@ export default { }, /** 重置查询操作 */ resetQuery() { + this.timeRange = []; this.resetForm("queryForm"); + this.queryParams = { + pageNum: 1, + //TODO 重置字段 + }; }, /** 搜索按钮操作 */ handleQuery() { @@ -222,7 +242,10 @@ export default { handleDelete(row) { // delXXX().then((res) => { // this.msgSuccess("删除成功"); +<<<<<<< HEAD +======= +>>>>>>> db49575a0ded0eef5e8a68461da1448cdacb3d69 // this.handleQuery(); // }); }, diff --git a/ZR.Vue/package.json b/ZR.Vue/package.json index 4b84f42..48dafb0 100644 --- a/ZR.Vue/package.json +++ b/ZR.Vue/package.json @@ -21,11 +21,11 @@ }, "dependencies": { "@riophae/vue-treeselect": "0.4.0", - "axios": "^0.21.1", + "axios": "^0.21.4", "clipboard": "2.0.4", "core-js": "3.6.5", "echarts": "^5.1.1", - "element-ui": "2.13.2", + "element-ui": "2.15.6", "file-saver": "2.0.1", "fuse.js": "3.4.4", "js-beautify": "1.10.2", diff --git a/ZR.Vue/public/index.html b/ZR.Vue/public/index.html index 6d64bf9..ad1a290 100644 --- a/ZR.Vue/public/index.html +++ b/ZR.Vue/public/index.html @@ -1,13 +1,16 @@ - - - - - - - <%= webpackConfig.name %> - - - -
-
-
-
-
-
正在加载系统资源,请耐心等待
-
-
- + + + +
+
+
+ +
+

+
+ + diff --git a/ZR.Vue/src/api/gendemo.js b/ZR.Vue/src/api/gendemo.js new file mode 100644 index 0000000..a7c6c3d --- /dev/null +++ b/ZR.Vue/src/api/gendemo.js @@ -0,0 +1,59 @@ +import request from '@/utils/request' + +/** + * 分页查询 + * @param {查询条件} data + */ +export function listGendemo(data) { + return request({ + url: '/bus/Gendemo/list', + method: 'get', + params: data, + }) +} + +/** + * 新增 + * @param data + */ +export function addGendemo(data) { + return request({ + url: '/bus/Gendemo', + method: 'post', + data: data, + }) +} + +/** + * 修改 + * @param data + */ +export function updateGendemo(data) { + return request({ + url: '/bus/Gendemo', + method: 'PUT', + data: data, + }) +} + +/** + * 获取详情 + * @param {Id} Id + */ +export function getGendemo(id) { + return request({ + url: '/bus/Gendemo/' + id, + method: 'get' + }) +} + +/** + * 删除 + * @param {主键} pid + */ +export function delGendemo(pid) { + return request({ + url: '/bus/Gendemo/' + pid, + method: 'delete' + }) +} diff --git a/ZR.Vue/src/api/monitor/operlog.js b/ZR.Vue/src/api/monitor/operlog.js index 07e27ab..58def23 100644 --- a/ZR.Vue/src/api/monitor/operlog.js +++ b/ZR.Vue/src/api/monitor/operlog.js @@ -26,10 +26,10 @@ export function cleanOperlog() { } // 导出操作日志 -export function exportOperlog(query) { - return request({ - url: '/monitor/operlog/export', - method: 'get', - params: query - }) -} +// export function exportOperlog(query) { +// return request({ +// url: '/monitor/operlog/export', +// method: 'get', +// params: query +// }) +// } diff --git a/ZR.Vue/src/api/login.js b/ZR.Vue/src/api/system/login.js similarity index 100% rename from ZR.Vue/src/api/login.js rename to ZR.Vue/src/api/system/login.js diff --git a/ZR.Vue/src/api/tool/gen.js b/ZR.Vue/src/api/tool/gen.js index 4506927..93d7a27 100644 --- a/ZR.Vue/src/api/tool/gen.js +++ b/ZR.Vue/src/api/tool/gen.js @@ -1,76 +1,84 @@ import request from '@/utils/request' -// 查询生成表数据 -export function listTable(query) { - return request({ - url: '/tool/gen/list', - method: 'get', - params: query - }) -} -// 查询db数据库列表 -export function listDbTable(query) { - return request({ - url: '/tool/gen/db/list', - method: 'get', - params: query - }) -} - -// 查询表详细信息 -export function getGenTable(tableId) { - return request({ - url: '/tool/gen/' + tableId, - method: 'get' - }) -} - -// 修改代码生成信息 -export function updateGenTable(data) { - return request({ - url: '/tool/gen', - method: 'put', - data: data - }) -} - -// 导入表 -export function importTable(data) { - return request({ - url: '/tool/gen/importTable', - method: 'post', - params: data - }) -} - // 预览生成代码 -export function previewTable(tableId) { +// export function previewTable(tableId) { +// return request({ +// url: '/tool/gen/preview/' + tableId, +// method: 'get' +// }) +// } + +/** + * 创建数据库连接 + */ +// export function createGetDBConn(data) { +// return request({ +// url: 'tool/gen/CreateDBConn', +// method: 'post', +// data: data, +// }) +// } +/** + * 获取数据库 + */ +export function codeGetDBList() { return request({ - url: '/tool/gen/preview/' + tableId, - method: 'get' + url: 'tool/gen/getDbList', + method: 'get', + }) +} +/** + * 获取数据库表 + */ +export function codeGetTableList(data) { + return request({ + url: 'tool/gen/getTableList', + method: 'get', + params: data, + }) +} +/** + * 生成代码 + */ +export async function codeGenerator(data) { + return await request({ + url: 'tool/gen/genCode', + method: 'post', + data: data, }) } -// 删除表数据 -export function delTable(tableId) { +/** + * 获取表格列信息 + * @param {*} data + * @returns + */ +export function queryColumnInfo(data) { return request({ - url: '/tool/gen/' + tableId, - method: 'delete' + url: 'tool/gen/getColumnInfo', + method: 'GET', + params: data, }) } -// 生成代码(自定义路径) -export function genCode(tableName) { - return request({ - url: '/tool/gen/genCode/' + tableName, - method: 'get' - }) -} - -// 同步数据库 -export function synchDb(tableName) { - return request({ - url: '/tool/gen/synchDb/' + tableName, - method: 'get' - }) -} +// /** +// * +// * 数据库解密 +// */ +// export function dbtoolsConnStrDecrypt(data) { +// return request({ +// url: 'DbTools/ConnStrDecrypt', +// method: 'post', +// params: data, +// }) +// } +// /** +// * 数据库加密 +// */ +// export function dbtoolsConnStrEncrypt(data) { +// return request({ +// url: 'DbTools/ConnStrEncrypt', +// method: 'post', +// params: data, +// }) +// } diff --git a/ZR.Vue/src/assets/styles/index.scss b/ZR.Vue/src/assets/styles/index.scss index 4133f95..7fbd419 100644 --- a/ZR.Vue/src/assets/styles/index.scss +++ b/ZR.Vue/src/assets/styles/index.scss @@ -480,3 +480,17 @@ aside { position: relative; float: right; } +.icon { + width: 100px; +} +// 上传文件按钮样式 +.uploader-icon { + width: 50px; + height: 50px; + line-height: 50px; + border: 1px dashed #ccc; + margin-bottom: 10px; +} +.table-td-thumb { + width: 80px; +} diff --git a/ZR.Vue/src/layout/components/Navbar.vue b/ZR.Vue/src/layout/components/Navbar.vue index 2d0df08..1e36156 100644 --- a/ZR.Vue/src/layout/components/Navbar.vue +++ b/ZR.Vue/src/layout/components/Navbar.vue @@ -6,16 +6,13 @@ -
@@ -85,9 +82,6 @@ export default { }); }); }, - to() { - this.$router.replace("/bigdata"); - }, }, }; diff --git a/ZR.Vue/src/main.js b/ZR.Vue/src/main.js index 912ad47..94685d3 100644 --- a/ZR.Vue/src/main.js +++ b/ZR.Vue/src/main.js @@ -2,11 +2,9 @@ import Vue from 'vue' import Cookies from 'js-cookie' -import 'normalize.css/normalize.css' // a modern alternative to CSS resets - import Element from 'element-ui' -import './assets/styles/element-variables.scss' - +import 'normalize.css/normalize.css' // a modern alternative to CSS resets +import '@/assets/styles/element-variables.scss' import '@/assets/styles/index.scss' // global css import App from './App' @@ -62,7 +60,7 @@ Vue.use(permission) */ Vue.use(Element, { - size: Cookies.get('size') || 'mini' // set element-ui default size + size: Cookies.get('size') || 'medium' // set element-ui default size }) Vue.config.productionTip = false diff --git a/ZR.Vue/src/store/modules/user.js b/ZR.Vue/src/store/modules/user.js index cc944ee..7a95dbd 100644 --- a/ZR.Vue/src/store/modules/user.js +++ b/ZR.Vue/src/store/modules/user.js @@ -1,4 +1,4 @@ -import { login, logOut, getInfo } from '@/api/login' +import { login, logOut, getInfo } from '@/api/system/login' import { getToken, setToken, removeToken } from '@/utils/auth' const user = { diff --git a/ZR.Vue/src/views/dashboard/bigdata.vue b/ZR.Vue/src/views/dashboard/bigdata.vue deleted file mode 100644 index f6caa73..0000000 --- a/ZR.Vue/src/views/dashboard/bigdata.vue +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - diff --git a/ZR.Vue/src/views/dashboard/bigdata/IviewCircle.vue b/ZR.Vue/src/views/dashboard/bigdata/IviewCircle.vue deleted file mode 100644 index a0deaed..0000000 --- a/ZR.Vue/src/views/dashboard/bigdata/IviewCircle.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - - diff --git a/ZR.Vue/src/views/dashboard/bigdata/chart-options.js b/ZR.Vue/src/views/dashboard/bigdata/chart-options.js deleted file mode 100644 index 98dfb75..0000000 --- a/ZR.Vue/src/views/dashboard/bigdata/chart-options.js +++ /dev/null @@ -1,471 +0,0 @@ -var echarts = require("echarts"); -let chartLeft1 = { - tooltip: { - trigger: "axis", - axisPointer: { - type: "shadow" - } - }, - grid: { - left: "0%", - top: "10px", - right: "0%", - bottom: "4%", - containLabel: true - }, - xAxis: [ - { - type: "category", - data: [ - "商超门店", - "教育培训", - "房地产", - "生活服务", - "汽车销售", - "旅游酒店", - "五金建材" - ], - axisLine: { - show: true, - lineStyle: { - color: "rgba(255,255,255,.1)", - width: 1, - type: "solid" - } - }, - - axisTick: { - show: false - }, - axisLabel: { - interval: 0, - show: true, - splitNumber: 15, - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: "12" - } - } - } - ], - yAxis: [ - { - type: "value", - axisLabel: { - show: true, - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: "12" - } - }, - axisTick: { - show: false - }, - axisLine: { - show: true, - lineStyle: { - color: "rgba(255,255,255,.1 )", - width: 1, - type: "solid" - } - }, - splitLine: { - lineStyle: { - color: "rgba(255,255,255,.1)" - } - } - } - ], - series: [ - { - type: "bar", - data: [200, 600, 300, 900, 1500, 1200, 600], - barWidth: "35%", - itemStyle: { - normal: { - color: "#2f89cf", - opacity: 1, - barBorderRadius: 5 - } - } - } - ] -}; - - -let chartLeft2 = { - tooltip: { - trigger: "axis", - axisPointer: { - type: "shadow" - } - }, - grid: { - left: "0%", - top: "10px", - right: "0%", - bottom: "4%", - containLabel: true - }, - xAxis: [ - { - type: "category", - data: [ - "07.01", - "07.02", - "07.03", - "07.04", - "07.05", - "07.06", - ], - axisLine: { - show: true, - lineStyle: { - color: "rgba(255,255,255,.1)", - width: 1, - type: "solid" - } - }, - axisTick: { - show: false - }, - axisLabel: { - interval: 0, - // rotate:50, - show: true, - splitNumber: 15, - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: "12" - } - } - } - ], - yAxis: [ - { - type: "value", - axisLabel: { - show: true, - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: "12" - } - }, - axisTick: { - show: false - }, - axisLine: { - show: true, - lineStyle: { - color: "rgba(255,255,255,.1 )", - width: 1, - type: "solid" - } - }, - splitLine: { - lineStyle: { - color: "rgba(255,255,255,.1)" - } - } - }, - { - type: "value", - axisLabel: { - show: true, - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: "12" - } - }, - axisTick: { - show: false - }, - axisLine: { - show: true, - lineStyle: { - color: "rgba(255,255,255,.1 )", - width: 1, - type: "solid" - } - }, - splitLine: { - lineStyle: { - color: "rgba(255,255,255,.1)" - } - } - } - ], series: [ - { - type: "bar", - name: "销量", - data: [1200, 800, 300, 500, 560, 220], - barWidth: "25%", - itemStyle: { - normal: { - color: "#2f89cf", - opacity: 1, - barBorderRadius: 5 - } - } - }, { - type: "bar", - name: "订单", - data: [1000, 750, 380, 450, 450, 120], - barWidth: "25%", - itemStyle: { - normal: { - color: "#46d000", - opacity: 1, - barBorderRadius: 5 - } - } - } - ] -}; - -let chartLeft3 = { - tooltip: { - trigger: 'axis', - axisPointer: { // 坐标轴指示器,坐标轴触发有效 - type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' - } - }, - grid: { - left: "0%", - top: "-5px", - right: "3%", - bottom: "4%", - containLabel: true - }, - xAxis: { - type: 'value', - axisLabel: { - show: true, - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: "12" - } - }, - axisTick: { - show: false - }, - axisLine: { - show: true, - lineStyle: { - color: "rgba(255,255,255,.1 )", - width: 1, - type: "solid" - } - }, - splitLine: { - lineStyle: { - color: "rgba(255,255,255,.1)" - } - } - }, - yAxis: { - type: 'category', - axisLabel: { - show: true, - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: "12" - } - }, - axisTick: { - show: false - }, - axisLine: { - show: true, - lineStyle: { - color: "rgba(255,255,255,.1 )", - width: 1, - type: "solid" - } - }, - splitLine: { - lineStyle: { - color: "rgba(255,255,255,.1)" - } - }, - data: ['周一', '周二', '周三', '周四', '周五'] - }, - series: [ - { - name: '直接访问', - type: 'bar', - stack: '总量', - label: { - show: true, - position: 'insideRight' - }, - barWidth: "55%", - itemStyle: { - normal: { - color: "#2f89cf", - opacity: 1, - barBorderRadius: 5 - } - }, - data: [120, 302, 400, 200, 700] - } - ] -}; - -let chartRight1 = { - title: {}, - tooltip: { - trigger: "axis", - axisPointer: { - type: "cross", - label: { - backgroundColor: "#6a7985" - } - } - }, - - color: ["#ffab6f", "#09b916", "#83cddc"], //图例颜色 - legend: { - top: "0%", - icon: "roundRect", - data: ["销售订单", "退货订单", "折扣订单"], - textStyle: { - color: "rgba(255,255,255,.5)", - fontSize: "12" - } - }, - toolbox: { - feature: {} - }, - grid: { - left: "10", - top: "20", - right: "10", - bottom: "10", - containLabel: true - }, - xAxis: [ - { - type: "category", - boundaryGap: false, - axisLabel: { - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: 12 - } - }, - axisLine: { - lineStyle: { - color: "rgba(255,255,255,.2)" - } - }, - data: [ - "2020.06.15", - "2020.06.16", - "2020.06.17", - "2020.06.18", - "2020.06.19", - "2020.06.20", - "2020.06.21", - "2020.06.22" - ] - } - ], - yAxis: [ - { - type: "value", - axisTick: { show: false }, - minInterval: 60, - axisLine: { - lineStyle: { - color: "rgba(255,255,255,.1)" - } - }, - axisLabel: { - textStyle: { - color: "rgba(255,255,255,.6)", - fontSize: 12 - } - }, - - splitLine: { - lineStyle: { - color: "rgba(255,255,255,.1)" - } - } - } - ], - series: [ - { - name: "销售订单", - type: "line", - smooth: true, - lineStyle: { - color: "#45d4ba", - width: 1 - }, //线条的样式 - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { - offset: 0, - color: "#83cddc" - }, - { - offset: 1, - color: "#bfdffbb5" - } - ]) - }, - data: [5, 22, 150, 54, 1, 230, 4, 1] - }, - { - name: "退货订单", - type: "line", - - smooth: true, - lineStyle: { - color: "#04a710", - width: 1 - }, // - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { - offset: 0, - color: "#0cbf22" - }, - { - offset: 1, - color: "#b8f7d1b5" - } - ]) - }, - data: [10, 150, 1, 250, 20, 100, 10, 150] - }, - { - name: "折扣订单", - type: "line", - - lineStyle: { - color: "#0864c3", - width: 1 - }, //线条的样式 - smooth: true, - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { - offset: 0, - color: "#29d7ff" - }, - { - offset: 1, - color: "#34ccef85" - } - ]) - }, - data: [100, 2, 260, 1, 200, 30, 101, 40] - } - ] -}; - - -export { chartLeft1, chartLeft2,chartLeft3, chartRight1 } diff --git a/ZR.Vue/src/views/dashboard/bigdata/head_bg.png b/ZR.Vue/src/views/dashboard/bigdata/head_bg.png deleted file mode 100644 index a2e45f6..0000000 Binary files a/ZR.Vue/src/views/dashboard/bigdata/head_bg.png and /dev/null differ diff --git a/ZR.Vue/src/views/dashboard/bigdata/layout.less b/ZR.Vue/src/views/dashboard/bigdata/layout.less deleted file mode 100644 index 3f6cffd..0000000 --- a/ZR.Vue/src/views/dashboard/bigdata/layout.less +++ /dev/null @@ -1,197 +0,0 @@ - -.big-data-container { - position: absolute; - overflow: hidden; - height: 100%; - width: 100%; - background-color: #1400a8; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' viewBox='0 0 1200 800'%3E%3Cdefs%3E%3CradialGradient id='a' cx='0' cy='800' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%230e0077'/%3E%3Cstop offset='1' stop-color='%230e0077' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='b' cx='1200' cy='800' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%2314057c'/%3E%3Cstop offset='1' stop-color='%2314057c' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='600' cy='0' r='600' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%230d0524'/%3E%3Cstop offset='1' stop-color='%230d0524' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='d' cx='600' cy='800' r='600' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%231400a8'/%3E%3Cstop offset='1' stop-color='%231400a8' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='e' cx='0' cy='0' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23000000'/%3E%3Cstop offset='1' stop-color='%23000000' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='f' cx='1200' cy='0' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23130733'/%3E%3Cstop offset='1' stop-color='%23130733' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect fill='url(%23a)' width='1200' height='800'/%3E%3Crect fill='url(%23b)' width='1200' height='800'/%3E%3Crect fill='url(%23c)' width='1200' height='800'/%3E%3Crect fill='url(%23d)' width='1200' height='800'/%3E%3Crect fill='url(%23e)' width='1200' height='800'/%3E%3Crect fill='url(%23f)' width='1200' height='800'/%3E%3C/svg%3E"); - background-attachment: fixed; - background-size: cover; - .head { - height: 75px; - /* height: 1.05rem; */ - background: url(./head_bg.png) no-repeat center center; - background-size: 100% 100%; - position: relative; - z-index: 100; - } -} - -.head h1 { - margin: 0; - color: #fff; - text-align: center; - /* font-size: .4rem; */ - /* line-height: .8rem; */ - line-height: 71px; -} - -.data-container { - /* margin: 5px 15px; - height:100%; */ - - margin: 0px 15px; - position: absolute; - left: 0; - right: 0; - top: 76px; - bottom: 0; -} - -.data-container > div { - float: left; - /* border: 1px solid white; */ - height: 100%; -} - -.data-center { - padding: 0 0.9rem; - width: 40%; - display: flex; - flex-direction: column; - // .center-top{ - // height: 210px; - // background: red; - // } -.chart-center{ - flex: 1; -} -} -.chart-center{ - width: 100%; -display: flex; -// background: white; -} -.data-left, -.data-right { - width: 30%; - display: flex; - - flex-direction: column; -} - -.data-left-item, -.data-right-item,.center-top,.center-top-num,.chart-center { - border: 1px solid rgba(25, 186, 139, 0.17); - padding: 0 0.2rem 0.4rem 0.15rem; - background: rgba(255, 255, 255, 0.04); - background-size: 100% auto; - position: relative; - margin-bottom: 0.15rem; - z-index: 10; -} - -.data-foot-line { - position: absolute; - bottom: 0; - width: 100%; - left: 0; -} - -.data-foot-line:before, -.data-foot-line:after { - position: absolute; - width: 10px; - height:10px; - content: ""; - border-bottom: 2px solid #02a6b5; - bottom: 0; -} - -.boxall:before, -.data-foot-line:before { - border-left: 2px solid #02a6b5; - left: 0; -} - -.boxall:after, -.data-foot-line:after { - border-right: 2px solid #02a6b5; - right: 0; -} - -.boxall:before, -.boxall:after { - position: absolute; - width: 10px; - height: 10px; - content: ""; - border-top: 2px solid #02a6b5; - top: 0; -} - -.data-left-item:before, -.data-right-item:before, -.center-top-num:before, -.center-top:before{ - border-left: 2px solid #02a6b5; - left: 0; - position: absolute; - width: 10px; - height:10px; - content: ""; - border-top: 2px solid #02a6b5; - top: 0; -} - -.data-left-item:after, -.data-right-item:after, -.center-top-num:after, -.center-top:after { - border-right: 2px solid #02a6b5; - right: 0; - position: absolute; - width: 10px; - height: 10px; - content: ""; - border-top: 2px solid #02a6b5; - top: 0; -} - -.data-left, -.data-right { - /* display: flex; */ -} - -.data-left > .data-left-item, -.data-right > .data-right-item { - flex: 1; - margin-bottom: 0.9rem; -} - -.data-center .title, -.data-left > .data-left-item .title, -.data-right > .data-right-item .title { - /* font-size: .2rem; */ - font-size: 1rem; - padding: 7px 0; - color: #fff; - text-align: center; - /* line-height: .5rem; */ -} - -.data-center .chart-center{ - width: 100%; -} - -.center-top-num{ - height: 80px; - padding-top: 7px; - margin-bottom: 0.8rem; - display: flex; - .item{ - flex: 1; - text-align: center; - } - .text{ - color: #fcf0d8; - font-size: 14px; - } - .num{ - font-size: 34px; - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; - font-weight: bold; - color: #67caca; - } -} diff --git a/ZR.Vue/src/views/demo.vue b/ZR.Vue/src/views/demo.vue index 51f7a1e..1355db5 100644 --- a/ZR.Vue/src/views/demo.vue +++ b/ZR.Vue/src/views/demo.vue @@ -87,35 +87,41 @@ - - - - - - - - - - - - - - - - - - - - {{dict.dictLabel}} - - - - - - - - - + + + + + + + + + + + + + + + + {{dict.dictLabel}} + + + + + + + + + + + + + + + + + + +