diff --git a/Infrastructure/Enums/StoreType.cs b/Infrastructure/Enums/StoreType.cs index 4dea7eb..79d8e6d 100644 --- a/Infrastructure/Enums/StoreType.cs +++ b/Infrastructure/Enums/StoreType.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.ComponentModel; namespace Infrastructure.Enums { @@ -30,5 +25,10 @@ namespace Infrastructure.Enums [Description("腾讯云")] TENCENT = 3, + /// + /// 七牛 + /// + [Description("七牛云")] + QINIU = 4 } } diff --git a/README.md b/README.md index 742c887..d0342ff 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ * 后端采用Net5/Net6、Sqlsugar、MySQL。 * 权限认证使用Jwt,支持多终端认证系统。 * 支持加载动态权限菜单,多方式轻松权限控制 +* 提供了技术栈(Ant Design Vue)版[Ant Design Vue](https://gitee.com/billzh/mc-dull.git) * 七牛云通用云产品优惠券:[点我进入](https://s.qiniu.com/FzEfay)。 * 腾讯云秒杀场:[点我进入](https://curl.qcloud.com/4yEoRquq)。 * 腾讯云优惠券:[点我领取](https://curl.qcloud.com/5J4nag8D)。 diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs index d36dff1..18e2433 100644 --- a/ZR.Admin.WebApi/Controllers/CommonController.cs +++ b/ZR.Admin.WebApi/Controllers/CommonController.cs @@ -1,5 +1,6 @@ using Infrastructure; using Infrastructure.Attribute; +using Infrastructure.Enums; using Infrastructure.Extensions; using Infrastructure.Model; using Microsoft.AspNetCore.Hosting; @@ -91,26 +92,60 @@ namespace ZR.Admin.WebApi.Controllers /// /// 存储目录 /// 自定义文件名 - /// 上传类型 1、发送邮件 + /// 上传类型1、保存到本地 2、保存到阿里云 /// [HttpPost()] [Verify] [ActionPermissionFilter(Permission = "common")] - public async Task UploadFile([FromForm(Name = "file")] IFormFile formFile, string fileName = "", string fileDir = "uploads", int uploadType = 0) + public async Task UploadFile([FromForm(Name = "file")] IFormFile formFile, string fileName = "", string fileDir = "uploads", StoreType storeType = StoreType.LOCAL) { if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); + SysFile file = new(); + string fileExt = Path.GetExtension(formFile.FileName);//文件后缀 + double fileSize = Math.Round(formFile.Length / 1024.0, 2);//文件大小KB + string[] NotAllowedFileExtensions = new string[] { ".bat", ".exe", ".jar", ".js" }; + int MaxContentLength = 15; + if (NotAllowedFileExtensions.Contains(fileExt)) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "上传失败,未经允许上传类型"); + } + switch (storeType) + { + case StoreType.LOCAL: + file = await SysFileService.SaveFileToLocal(WebHostEnvironment.WebRootPath, fileName, fileDir, HttpContext.GetName(), formFile); - SysFile file = await SysFileService.SaveFileToLocal(WebHostEnvironment.WebRootPath, fileName, fileDir, HttpContext.GetName(), formFile); + break; + case StoreType.ALIYUN: + if ((fileSize / 1024) > MaxContentLength) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + MaxContentLength + " MB"); + } + file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", fileDir, HttpContext.GetName()) + { + StoreType = (int)StoreType.ALIYUN, + FileType = formFile.ContentType + }; + file = await SysFileService.SaveFileToAliyun(file, formFile); + + if (file.Id <= 0) { return ToResponse(ApiResult.Error("阿里云连接失败")); } + break; + case StoreType.TENCENT: + break; + case StoreType.QINIU: + break; + default: + break; + } return SUCCESS(new { - url = uploadType == 1 ? file.FileUrl : file.AccessUrl, + url = file.AccessUrl, fileName, fileId = file.Id.ToString() }); } /// - /// 存储文件到阿里云 + /// 存储文件到阿里云(已弃用) /// /// /// 自定义文件名 @@ -134,7 +169,7 @@ namespace ZR.Admin.WebApi.Controllers { return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + MaxContentLength + " MB"); } - SysFile file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", fileDir, "", HttpContext.GetName()) + SysFile file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", fileDir, HttpContext.GetName()) { StoreType = (int)Infrastructure.Enums.StoreType.ALIYUN, FileType = formFile.ContentType diff --git a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs index 3694650..2b89b4c 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs @@ -86,8 +86,8 @@ namespace ZR.Admin.WebApi.Controllers.System List permissions = permissionService.GetMenuPermission(user); LoginUser loginUser = new(user, roles, permissions); - CacheHelper.SetCache(GlobalConstant.UserPermKEY + user.UserId, loginUser); - return SUCCESS(JwtUtil.GenerateJwtToken(HttpContext.AddClaims(loginUser), jwtSettings.JwtSettings)); + CacheHelper.SetCache(GlobalConstant.UserPermKEY + user.UserId, permissions); + return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), jwtSettings.JwtSettings)); } /// @@ -103,11 +103,11 @@ namespace ZR.Admin.WebApi.Controllers.System // //注销登录的用户,相当于ASP.NET中的FormsAuthentication.SignOut // await HttpContext.SignOutAsync(); //}).Wait(); - var id = HttpContext.GetUId(); + var userid = HttpContext.GetUId(); var name = HttpContext.GetName(); - - CacheHelper.Remove(GlobalConstant.UserPermKEY + id); - return SUCCESS(new { name , id}); + + CacheHelper.Remove(GlobalConstant.UserPermKEY + userid); + return SUCCESS(new { name , id = userid }); } /// diff --git a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs index 5f8420b..9f6b0a5 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.IO; using System.Linq; +using ZR.Admin.WebApi.Extensions; using ZR.Admin.WebApi.Filters; using ZR.Common; using ZR.Model; @@ -94,7 +95,7 @@ namespace ZR.Admin.WebApi.Controllers.System return ToResponse(ApiResult.Error($"新增用户 '{user.UserName}'失败,登录账号已存在")); } - user.Create_by = User.Identity.Name; + user.Create_by = HttpContext.GetName(); user.Password = NETCore.Encrypt.EncryptProvider.Md5(user.Password); return ToResponse(UserService.InsertUser(user)); @@ -112,7 +113,7 @@ namespace ZR.Admin.WebApi.Controllers.System { if (user == null || user.UserId <= 0) { return ToResponse(ApiResult.Error(101, "请求参数错误")); } - user.Update_by = User.Identity.Name; + user.Update_by = HttpContext.GetName(); int upResult = UserService.UpdateUser(user); return ToResponse(upResult); diff --git a/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs b/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs index 988a148..14d6b4f 100644 --- a/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs +++ b/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs @@ -130,27 +130,6 @@ namespace ZR.Admin.WebApi.Extensions return context != null ? context.Request.Path.Value : ""; } - /// - ///组装Claims - /// - /// - /// - /// - public static List AddClaims(this HttpContext context, LoginUser user) - { - //1、创建Cookie保存用户信息,使用claim - var claims = new List() - { - new Claim(ClaimTypes.PrimarySid, user.UserId.ToString()), - new Claim(ClaimTypes.Name, user.UserName), - new Claim(ClaimTypes.UserData, JsonConvert.SerializeObject(user)) - }; - - //写入Cookie - //WhiteCookie(context, claims); - return claims; - } - private static void WhiteCookie(HttpContext context, List claims) { //2.创建声明主题 指定认证方式 这里使用cookie diff --git a/ZR.Admin.WebApi/Extensions/TasksExtension.cs b/ZR.Admin.WebApi/Extensions/TasksExtension.cs index 2ca150e..018a19c 100644 --- a/ZR.Admin.WebApi/Extensions/TasksExtension.cs +++ b/ZR.Admin.WebApi/Extensions/TasksExtension.cs @@ -33,11 +33,12 @@ namespace ZR.Admin.WebApi.Extensions /// public static IApplicationBuilder UseAddTaskSchedulers(this IApplicationBuilder app) { - var _tasksQzService = (ISysTasksQzService)App.GetRequiredService(typeof(ISysTasksQzService)); + //var _tasksQzService = (ISysTasksQzService)App.GetRequiredService(typeof(ISysTasksQzService)); ITaskSchedulerServer _schedulerServer = App.GetRequiredService(); - var tasks = _tasksQzService.GetList(m => m.IsStart); + //var tasks = _tasksQzService.GetList(m => m.IsStart); + var tasks = SqlSugar.IOC.DbScoped.SugarScope.Queryable().Where(m => m.IsStart).ToList(); //程序启动后注册所有定时任务 foreach (var task in tasks) diff --git a/ZR.Admin.WebApi/Framework/JwtUtil.cs b/ZR.Admin.WebApi/Framework/JwtUtil.cs index a7a1b01..f74dd03 100644 --- a/ZR.Admin.WebApi/Framework/JwtUtil.cs +++ b/ZR.Admin.WebApi/Framework/JwtUtil.cs @@ -6,6 +6,7 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using ZR.Admin.WebApi.Extensions; +using ZR.Common; using ZR.Model.System; namespace ZR.Admin.WebApi.Framework @@ -124,9 +125,15 @@ namespace ZR.Admin.WebApi.Framework { try { - var userData = jwtToken.FirstOrDefault(x => x.Type == ClaimTypes.UserData); - - LoginUser loginUser = JsonConvert.DeserializeObject(value: userData?.Value); + var userData = jwtToken.FirstOrDefault(x => x.Type == ClaimTypes.UserData).Value; + var loginUser = JsonConvert.DeserializeObject(userData); + var permissions = (List)CacheHelper.GetCache(GlobalConstant.UserPermKEY + loginUser?.UserId); + if (loginUser?.UserName == "admin") + { + permissions = new List() { GlobalConstant.AdminPerm }; + } + if (permissions == null) return null; + loginUser.Permissions = permissions; return loginUser; } catch (Exception ex) @@ -135,5 +142,27 @@ namespace ZR.Admin.WebApi.Framework return null; } } + + /// + ///组装Claims + /// + /// + /// + public static List AddClaims(LoginUser user) + { + if (user?.Permissions.Count > 50) + { + user.Permissions = new List(); + } + var claims = new List() + { + new Claim(ClaimTypes.PrimarySid, user.UserId.ToString()), + new Claim(ClaimTypes.Name, user.UserName), + new Claim(ClaimTypes.UserData, JsonConvert.SerializeObject(user)) + }; + + return claims; + } + } } diff --git a/ZR.CodeGenerator/CodeGenerateTemplate.cs b/ZR.CodeGenerator/CodeGenerateTemplate.cs index 03fcdbc..4e526c2 100644 --- a/ZR.CodeGenerator/CodeGenerateTemplate.cs +++ b/ZR.CodeGenerator/CodeGenerateTemplate.cs @@ -89,7 +89,7 @@ namespace ZR.CodeGenerator //图片 sb.AppendLine(" "); sb.AppendLine($" "); - sb.AppendLine($@" "); + sb.AppendLine($@" "); sb.AppendLine(" "); sb.AppendLine(" "); } diff --git a/ZR.Common/AliyunOssHelper.cs b/ZR.Common/AliyunOssHelper.cs index 4c9bf97..b45c87a 100644 --- a/ZR.Common/AliyunOssHelper.cs +++ b/ZR.Common/AliyunOssHelper.cs @@ -43,5 +43,25 @@ namespace ZR.Common return System.Net.HttpStatusCode.BadRequest; } + /// + /// 删除资源 + /// + /// + /// + /// + public static System.Net.HttpStatusCode DeleteFile(string dirPath, string bucketName = "") + { + if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; } + try + { + OssClient client = new(endpoint, accessKeyId, accessKeySecret); + DeleteObjectResult putObjectResult = client.DeleteObject(bucketName, dirPath); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + return System.Net.HttpStatusCode.BadRequest; + } } } diff --git a/ZR.Model/System/LoginUser.cs b/ZR.Model/System/LoginUser.cs index 9b5e797..013a9d1 100644 --- a/ZR.Model/System/LoginUser.cs +++ b/ZR.Model/System/LoginUser.cs @@ -24,7 +24,7 @@ namespace ZR.Model.System /// /// 权限集合 /// - public List Permissions { get; set; } + public List Permissions { get; set; } = new List(); public LoginUser() { } diff --git a/ZR.Model/System/SysFile.cs b/ZR.Model/System/SysFile.cs index 501b9c0..81c75be 100644 --- a/ZR.Model/System/SysFile.cs +++ b/ZR.Model/System/SysFile.cs @@ -72,14 +72,13 @@ namespace ZR.Model.System public string AccessUrl { get; set; } public SysFile() { } - public SysFile(string originFileName, string fileName, string ext, string fileSize, string storePath, string accessUrl,string create_by) + public SysFile(string originFileName, string fileName, string ext, string fileSize, string storePath, string create_by) { StorePath = storePath; RealName = originFileName; FileName = fileName; FileExt = ext; FileSize = fileSize; - AccessUrl = accessUrl; Create_by = create_by; Create_time = DateTime.Now; } diff --git a/ZR.Service/System/IService/ISysTasksLogService.cs b/ZR.Service/System/IService/ISysTasksLogService.cs index fe0815d..381796a 100644 --- a/ZR.Service/System/IService/ISysTasksLogService.cs +++ b/ZR.Service/System/IService/ISysTasksLogService.cs @@ -1,4 +1,5 @@ -using ZR.Model.System; +using System.Threading.Tasks; +using ZR.Model.System; using ZR.Repository; namespace ZR.Service.System.IService @@ -10,6 +11,6 @@ namespace ZR.Service.System.IService /// /// //public int AddTaskLog(string jobId); - SysTasksLog AddTaskLog(string jobId, SysTasksLog tasksLog); + Task AddTaskLog(string jobId, SysTasksLog tasksLog); } } diff --git a/ZR.Service/System/SysFileService.cs b/ZR.Service/System/SysFileService.cs index bfc8ca3..0b455c4 100644 --- a/ZR.Service/System/SysFileService.cs +++ b/ZR.Service/System/SysFileService.cs @@ -51,14 +51,15 @@ namespace ZR.Service.System using (var stream = new FileStream(finalFilePath, FileMode.Create)) { - await formFile.CopyToAsync(stream); + await formFile.CopyToAsync(stream);//await 不能少 } string accessPath = string.Concat(OptionsSetting.Upload.UploadUrl, "/", filePath.Replace("\\", "/"), "/", fileName); - SysFile file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", filePath, accessPath, userName) + SysFile file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", filePath, userName) { StoreType = (int)Infrastructure.Enums.StoreType.LOCAL, FileType = formFile.ContentType, - FileUrl = finalFilePath + FileUrl = finalFilePath, + AccessUrl = accessPath }; file.Id = await InsertFile(file); return file; diff --git a/ZR.Service/System/SysTasksLogService.cs b/ZR.Service/System/SysTasksLogService.cs index 4e66a94..61c9ec6 100644 --- a/ZR.Service/System/SysTasksLogService.cs +++ b/ZR.Service/System/SysTasksLogService.cs @@ -1,6 +1,7 @@ using Infrastructure.Attribute; using System; using System.Linq.Expressions; +using System.Threading.Tasks; using ZR.Model; using ZR.Model.System; using ZR.Repository; @@ -12,7 +13,7 @@ namespace ZR.Service.System /// 任务日志 /// [AppService(ServiceLifetime = LifeTime.Transient, ServiceType = typeof(ISysTasksLogService))] - public class SysTasksLogService : BaseRepository, ISysTasksLogService + public class SysTasksLogService : BaseService, ISysTasksLogService { private ISysTasksQzService _tasksQzService; public SysTasksLogService(ISysTasksQzService tasksQzService) @@ -20,10 +21,10 @@ namespace ZR.Service.System _tasksQzService = tasksQzService; } - public SysTasksLog AddTaskLog(string jobId, SysTasksLog logModel) + public async Task AddTaskLog(string jobId, SysTasksLog logModel) { //获取任务信息 - var model = _tasksQzService.GetId(jobId); + var model = await _tasksQzService.GetSingleAsync(f => f.ID == jobId); if (model != null) { @@ -33,7 +34,7 @@ namespace ZR.Service.System logModel.CreateTime = DateTime.Now; } - Add(logModel); + await InsertAsync(logModel); return logModel; } diff --git a/ZR.Tasks/TaskScheduler/JobBase.cs b/ZR.Tasks/TaskScheduler/JobBase.cs index 38a0780..5d27c75 100644 --- a/ZR.Tasks/TaskScheduler/JobBase.cs +++ b/ZR.Tasks/TaskScheduler/JobBase.cs @@ -56,7 +56,7 @@ namespace ZR.Tasks JobMessage = logMsg }; - RecordTaskLog(context, logModel); + await RecordTaskLog(context, logModel); return logModel; } @@ -65,7 +65,7 @@ namespace ZR.Tasks /// /// /// - protected void RecordTaskLog(IJobExecutionContext context, SysTasksLog logModel) + protected async Task RecordTaskLog(IJobExecutionContext context, SysTasksLog logModel) { var tasksLogService = (ISysTasksLogService)App.GetRequiredService(typeof(ISysTasksLogService)); var taskQzService = (ISysTasksQzService)App.GetRequiredService(typeof(ISysTasksQzService)); @@ -74,15 +74,15 @@ namespace ZR.Tasks IJobDetail job = context.JobDetail; logModel.InvokeTarget = job.JobType.FullName; - logModel = tasksLogService.AddTaskLog(job.Key.Name, logModel); + logModel = await tasksLogService.AddTaskLog(job.Key.Name, logModel); //成功后执行次数+1 if (logModel.Status == "0") { - taskQzService.Update(f => f.ID == job.Key.Name, f => new SysTasksQz() + await taskQzService.UpdateAsync(f => new SysTasksQz() { RunTimes = f.RunTimes + 1, LastRunTime = DateTime.Now - }); + }, f => f.ID == job.Key.Name); } logger.Info($"执行任务【{job.Key.Name}|{logModel.JobName}】结果={logModel.JobMessage}"); } diff --git a/ZR.Tasks/TaskSchedulerServer.cs b/ZR.Tasks/TaskSchedulerServer.cs index 681c405..0130aad 100644 --- a/ZR.Tasks/TaskSchedulerServer.cs +++ b/ZR.Tasks/TaskSchedulerServer.cs @@ -123,6 +123,10 @@ namespace ZR.Tasks { return ApiResult.Error(500, $"该计划任务已经在执行:【{tasksQz.Name}】,请勿重复添加!"); } + if (tasksQz?.EndTime <= DateTime.Now) + { + return ApiResult.Error(500, $"结束时间小于当前时间计划将不会被执行"); + } #region 设置开始时间和结束时间 tasksQz.BeginTime = tasksQz.BeginTime == null ? DateTime.Now : tasksQz.BeginTime; @@ -166,10 +170,12 @@ namespace ZR.Tasks // 5、将触发器和任务器绑定到调度器中 await _scheduler.Result.ScheduleJob(job, trigger); //任务没有启动、暂停任务 - if (!tasksQz.IsStart) - { - _scheduler.Result.PauseJob(jobKey).Wait(); - } + //if (!tasksQz.IsStart) + //{ + // _scheduler.Result.PauseJob(jobKey).Wait(); + //} + //按新的trigger重新设置job执行 + await _scheduler.Result.ResumeTrigger(trigger.Key); return ApiResult.Success($"启动计划任务:【{tasksQz.Name}】成功!"); } catch (Exception ex) diff --git a/ZR.Vue/src/components/FileUpload/index.vue b/ZR.Vue/src/components/FileUpload/index.vue index 14d85de..a8a9eaf 100644 --- a/ZR.Vue/src/components/FileUpload/index.vue +++ b/ZR.Vue/src/components/FileUpload/index.vue @@ -52,7 +52,7 @@ export default { // 文件类型, 例如['png', 'jpg', 'jpeg'] fileType: { type: Array, - default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf', 'svga', 'json'] + default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf', 'json'] }, // 是否显示提示 isShowTip: { diff --git a/ZR.Vue/src/components/UploadImage/index.vue b/ZR.Vue/src/components/UploadImage/index.vue index 8bf4f22..3317d27 100644 --- a/ZR.Vue/src/components/UploadImage/index.vue +++ b/ZR.Vue/src/components/UploadImage/index.vue @@ -1,7 +1,7 @@