diff --git a/Infrastructure/WebExtensions/LogoExtension.cs b/Infrastructure/WebExtensions/LogoExtension.cs index 577be4cc..20fd26d7 100644 --- a/Infrastructure/WebExtensions/LogoExtension.cs +++ b/Infrastructure/WebExtensions/LogoExtension.cs @@ -20,7 +20,7 @@ public static void AddLogo(this IServiceCollection services) Console.WriteLine("💰打赏作者:http://www.izhaorui.cn/vip"); Console.WriteLine("📱移动端体验:http://demo.izhaorui.cn/h5"); Console.WriteLine($"Swagger地址:{url}/swagger/index.html"); - Console.WriteLine($"初始化种子数据:{url}/common/InitSeedData"); + Console.WriteLine($"初始化种子数据地址:{url}/common/InitSeedData"); } } } diff --git a/ZR.Admin.WebApi/Controllers/Article/ArticleController.cs b/ZR.Admin.WebApi/Controllers/Article/ArticleController.cs index 738ded31..4056968f 100644 --- a/ZR.Admin.WebApi/Controllers/Article/ArticleController.cs +++ b/ZR.Admin.WebApi/Controllers/Article/ArticleController.cs @@ -3,12 +3,12 @@ using ZR.Admin.WebApi.Filters; using ZR.Model.System; using ZR.Model.System.Dto; - +using ZR.ServiceCore.Model.Enums; namespace ZR.Admin.WebApi.Controllers { /// - /// 文章管理 + /// 内容管理 /// [Verify] [Route("article")] @@ -190,5 +190,6 @@ public IActionResult Delete(int id = 0) var response = _ArticleService.Delete(id); return SUCCESS(response); } + } } \ No newline at end of file diff --git a/ZR.Admin.WebApi/Controllers/Article/MonentController.cs b/ZR.Admin.WebApi/Controllers/Article/MonentController.cs new file mode 100644 index 00000000..7ea92ccf --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/Article/MonentController.cs @@ -0,0 +1,143 @@ +using Microsoft.AspNetCore.Mvc; +using ZR.Admin.WebApi.Filters; +using ZR.Model.System; +using ZR.Model.System.Dto; +using ZR.ServiceCore.Model.Enums; + +namespace ZR.Admin.WebApi.Controllers +{ + [Verify] + [Route("monent")] + public class MonentController : BaseController + { + /// + /// 动态接口 + /// + private readonly IArticleService _ArticleService; + private readonly IArticleCategoryService _ArticleCategoryService; + + public MonentController(IArticleService ArticleService, IArticleCategoryService articleCategoryService) + { + _ArticleService = ArticleService; + _ArticleCategoryService = articleCategoryService; + } + + /// + /// 查询我的 + /// + /// + [HttpGet("mylist")] + public IActionResult QueryMyList([FromQuery] ArticleQueryDto parm) + { + parm.UserId = HttpContext.GetUId(); + parm.ArticleType = 2; + var response = _ArticleService.GetMyList(parm); + + return SUCCESS(response); + } + + /// + /// 查询动态列表 + /// + /// + [HttpGet("monentList")] + [AllowAnonymous] + public IActionResult QueryMonentList([FromQuery] ArticleQueryDto parm) + { + parm.UserId = HttpContext.GetUId(); + parm.ArticleType = 2; + var response = _ArticleService.GetArticleList(parm); + + return SUCCESS(response); + } + + /// + /// 置顶 + /// + /// + [HttpPut("top")] + [Log(Title = "置顶动态", BusinessType = BusinessType.UPDATE)] + public IActionResult Top([FromBody] Article parm) + { + var response = _ArticleService.TopArticle(parm); + + return SUCCESS(response); + } + + /// + /// 修改可见范围 + /// + /// + [HttpPut("changePublic")] + [Log(Title = "是否公开", BusinessType = BusinessType.UPDATE)] + public IActionResult ChangePublic([FromBody] Article parm) + { + var response = _ArticleService.ChangeArticlePublic(parm); + + return SUCCESS(response); + } + + /// + /// 动态发布 + /// + /// + [HttpPost("publishMonent")] + [Log(Title = "动态发布", BusinessType = BusinessType.INSERT)] + public IActionResult PublishMonent([FromBody] ArticleDto parm) + { + var addModel = parm.Adapt
().ToCreate(context: HttpContext); + addModel.AuthorName = HttpContext.GetName(); + addModel.UserId = HttpContext.GetUId(); + addModel.ArticleType = ArticleTypeEnum.Monent; + addModel.UserIP = HttpContext.GetClientUserIp(); + + string location = HttpContextExtension.GetIpInfo(addModel.UserIP); + addModel.Location = location; + return SUCCESS(_ArticleService.InsertReturnIdentity(addModel)); + } + + /// + /// 删除动态 + /// + /// + [HttpDelete("del/{id}")] + [Log(Title = "动态删除", BusinessType = BusinessType.DELETE)] + public IActionResult DeleteMonents(int id = 0) + { + var userId = HttpContext.GetUId(); + var info = _ArticleService.GetId(id); + if (info == null || info.UserId != userId) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "删除失败(-1)"); + } + var response = _ArticleService.Delete(id); + return SUCCESS(response); + } + + /// + /// 点赞动态 + /// + /// + [HttpPost("praise/{id}")] + public IActionResult PraiseMonents(int id = 0) + { + var response = _ArticleService.PraiseArticle(id); + return SUCCESS(response); + } + + /// + /// 动态信息 + /// + /// + [HttpDelete("getInfo")] + public IActionResult GetInfo() + { + var userId = HttpContext.GetUId(); + + var monentNum = _ArticleService.Queryable() + .Count(f => f.UserId == userId && f.ArticleType == ArticleTypeEnum.Monent); + + return SUCCESS(new { monentNum, commentNum = 0 }); + } + } +} diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs index 5afea0c9..24f4bcda 100644 --- a/ZR.Admin.WebApi/Controllers/CommonController.cs +++ b/ZR.Admin.WebApi/Controllers/CommonController.cs @@ -1,5 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; +using MiniExcelLibs; +using System.IO; using ZR.Admin.WebApi.Filters; using ZR.Model.System; using ZR.Service.IService; @@ -86,9 +88,9 @@ public IActionResult SendMsg(string msg, string toUser = "") [ActionPermissionFilter(Permission = "common")] public async Task UploadFile([FromForm] UploadDto uploadDto, StoreType storeType = StoreType.LOCAL) { - IFormFile formFile = uploadDto.File; - if (formFile == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); + if (uploadDto?.File == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); SysFile file = new(); + IFormFile formFile = uploadDto.File; string fileExt = Path.GetExtension(formFile.FileName);//文件后缀 double fileSize = Math.Round(formFile.Length / 1024.0, 2);//文件大小KB @@ -194,7 +196,7 @@ public IActionResult InitSeedData(bool clean = false) { if (!WebHostEnvironment.IsDevelopment()) { - return ToResponse(ResultCode.CUSTOM_ERROR, "导入数据失败"); + return ToResponse(ResultCode.CUSTOM_ERROR, "导入数据失败,请在开发模式下初始化"); } var path = Path.Combine(WebHostEnvironment.WebRootPath, "data.xlsx"); SeedDataService seedDataService = new(); @@ -210,5 +212,34 @@ public IActionResult InitSeedData(bool clean = false) result }); } + + /// + /// + /// + /// + [HttpGet] + [ActionPermissionFilter(Permission = "common")] + [Log(BusinessType = BusinessType.INSERT, Title = "初始化数据")] + public IActionResult UpdateSeedData() + { + if (!WebHostEnvironment.IsDevelopment()) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "导入数据失败,请在开发模式下初始化"); + } + var path = Path.Combine(WebHostEnvironment.WebRootPath, "data.xlsx"); + SeedDataService seedDataService = new(); + + var sysNotice = MiniExcel.Query(path, sheetName: "notice").ToList(); + var result = seedDataService.InitNoticeData(sysNotice); + + var sysMenu = MiniExcel.Query(path, sheetName: "menu").Where(f => f.MenuId >= 1104).ToList(); + var result5 = seedDataService.InitMenuData(sysMenu); + + return SUCCESS(new + { + result, + result5 + }); + } } } diff --git a/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs b/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs index af3c1bf9..33a667b7 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs @@ -31,7 +31,7 @@ public SysDeptController(ISysDeptService deptService [HttpGet("list")] public IActionResult List([FromQuery] SysDeptQueryDto dept) { - return SUCCESS(DeptService.GetSysDepts(dept), TIME_FORMAT_FULL); + return SUCCESS(DeptService.GetList(dept)); } /// @@ -42,11 +42,11 @@ public IActionResult List([FromQuery] SysDeptQueryDto dept) [HttpGet("list/exclude/{deptId}")] public IActionResult ExcludeChild(long deptId) { - var depts = DeptService.GetSysDepts(new SysDeptQueryDto()); + var depts = DeptService.GetList(new SysDeptQueryDto()); for (int i = 0; i < depts.Count; i++) { - SysDept d = depts[i]; + SysDeptDto d = depts[i]; long[] deptIds = Tools.SpitLongArrary(d.Ancestors); if (d.DeptId == deptId || ((IList)deptIds).Contains(deptId)) { diff --git a/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs b/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs index 7142e0d3..9c704734 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; using ZR.Admin.WebApi.Filters; using ZR.Model; using ZR.Model.System; @@ -39,7 +40,7 @@ public IActionResult List([FromQuery] SysDictData dictData, [FromQuery] PagerInf { var result = SysDictService.SelectDictDataByCustomSql(dictData.DictType); - list.Result.AddRange(result); + list.Result.AddRange(result.Adapt>()); list.TotalNum += result.Count; } return SUCCESS(list); @@ -64,26 +65,45 @@ public IActionResult DictType(string dictType) /// [AllowAnonymous] [HttpPost("types")] - public IActionResult DictTypes([FromBody] List dto) + public IActionResult DictTypes([FromBody] List dto) { var list = SysDictDataService.SelectDictDataByTypes(dto.Select(f => f.DictType).ToArray()); - List dataVos = new(); + var dataVos = GetDicts(dto.Select(f => f.DictType).ToArray()); - foreach (var dic in dto) + return SUCCESS(dataVos); + } + + /// + /// 移动端使用uniapp + /// + /// + [AllowAnonymous] + [HttpPost("dicts")] + public IActionResult GetDictTypes() + { + var data = HttpContext.GetBody(); + return SUCCESS(GetDicts(JsonConvert.DeserializeObject(data))); + } + + private List GetDicts([FromBody]string[] dicts) + { + List dataVos = new(); + var list = SysDictDataService.SelectDictDataByTypes(dicts); + + foreach (var dic in dicts) { - SysdictDataDto vo = new() + SysdictDataParamDto vo = new() { - DictType = dic.DictType, - ColumnName = dic.ColumnName, - List = list.FindAll(f => f.DictType == dic.DictType) + DictType = dic, + List = list.FindAll(f => f.DictType == dic) }; - if (dic.DictType.StartsWith("cus_") || dic.DictType.StartsWith("sql_")) + if (dic.StartsWith("cus_") || dic.StartsWith("sql_")) { - vo.List.AddRange(SysDictService.SelectDictDataByCustomSql(dic.DictType)); + vo.List.AddRange(SysDictService.SelectDictDataByCustomSql(dic)); } dataVos.Add(vo); } - return SUCCESS(dataVos); + return dataVos; } /// diff --git a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs index e6d88804..3fdd901f 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs @@ -112,8 +112,8 @@ public IActionResult GetUserInfo() //权限集合 eg *:*:*,system:user:list List permissions = permissionService.GetMenuPermission(user); user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)]; - - return SUCCESS(new { user, roles, permissions }); + user.Password = string.Empty; + return SUCCESS(new { user = user.Adapt(), roles, permissions }); } /// diff --git a/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs b/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs index 4b7c9e2d..22349dec 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs @@ -117,7 +117,7 @@ public IActionResult MenuEdit([FromBody] MenuDto menuDto) .NameMatchingStrategy(NameMatchingStrategy.IgnoreCase);//忽略字段名称的大小写;//忽略除以上配置的所有字段 var modal = menuDto.Adapt(config).ToUpdate(HttpContext); - if (UserConstants.YES_FRAME.Equals(modal.IsFrame) && !modal.Path.StartsWith("http")) + if (UserConstants.YES_FRAME.Equals(modal.IsFrame) && (!modal.Path.StartsWith("http") && !modal.Path.StartsWith("/link"))) { return ToResponse(ApiResult.Error($"修改菜单'{modal.MenuName}'失败,地址必须以http(s)://开头")); } diff --git a/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs b/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs index 0c3b91bf..c11fb811 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs @@ -154,5 +154,25 @@ public IActionResult DeleteSysNotice(string ids) return SUCCESS(response); } + + /// + /// 导出通知公告表 + /// + /// + [Log(Title = "通知公告表", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)] + [HttpGet("export")] + [ActionPermissionFilter(Permission = "system:notice:export")] + public IActionResult Export([FromQuery] SysNoticeQueryDto parm) + { + parm.PageNum = 1; + parm.PageSize = 100000; + var list = _SysNoticeService.ExportList(parm).Result; + if (list == null || list.Count <= 0) + { + return ToResponse(ResultCode.FAIL, "没有要导出的数据"); + } + var result = ExportExcelMini(list, "通知公告表", "通知公告表"); + return ExportExcel(result.Item2, result.Item1); + } } } \ No newline at end of file diff --git a/ZR.Admin.WebApi/Controllers/System/SysPostController.cs b/ZR.Admin.WebApi/Controllers/System/SysPostController.cs index 9a1b360c..694867b7 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysPostController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysPostController.cs @@ -1,9 +1,9 @@ using Microsoft.AspNetCore.Mvc; using SqlSugar; using ZR.Admin.WebApi.Filters; -using ZR.Model; using ZR.Model.System; - +using ZR.Repository; +using ZR.ServiceCore.Model.Dto; namespace ZR.Admin.WebApi.Controllers.System { @@ -27,11 +27,20 @@ public SysPostController(ISysPostService postService) /// [HttpGet("list")] [ActionPermissionFilter(Permission = "system:post:list")] - public IActionResult List([FromQuery] SysPost post, [FromQuery] PagerInfo pagerInfo) + public IActionResult List([FromQuery] SysPostQueryDto dto) { var predicate = Expressionable.Create(); - predicate = predicate.AndIF(post.Status.IfNotEmpty(), it => it.Status == post.Status); - var list = PostService.GetPages(predicate.ToExpression(), pagerInfo, s => new { s.PostSort }); + predicate = predicate.AndIF(dto.Status.IfNotEmpty(), it => it.Status == dto.Status); + predicate = predicate.AndIF(dto.PostName.IfNotEmpty(), it => it.PostName.Contains(dto.PostName)); + predicate = predicate.AndIF(dto.PostCode.IfNotEmpty(), it => it.PostCode.Contains(dto.PostCode)); + + var list = PostService.Queryable() + .Where(predicate.ToExpression()) + .Select((it) => new SysPostDto + { + UserNum = SqlFunc.Subqueryable().Where(f => f.PostId == it.PostId).Sum(f => f.UserId) + }, true) + .ToPage(dto); return SUCCESS(list); } diff --git a/ZR.Admin.WebApi/Controllers/System/TasksController.cs b/ZR.Admin.WebApi/Controllers/System/TasksController.cs index f1897a3c..97ae5251 100644 --- a/ZR.Admin.WebApi/Controllers/System/TasksController.cs +++ b/ZR.Admin.WebApi/Controllers/System/TasksController.cs @@ -87,7 +87,6 @@ public IActionResult Create([FromBody] TasksCreateDto parm) } //从 Dto 映射到 实体 var tasksQz = parm.Adapt().ToCreate(HttpContext); - tasksQz.Create_by = HttpContext.GetName(); tasksQz.ID = SnowFlakeSingle.Instance.NextId().ToString(); return SUCCESS(_tasksQzService.AddTasks(tasksQz)); @@ -125,8 +124,7 @@ public async Task Update([FromBody] TasksCreateDto parm) { throw new CustomException($"该任务正在运行中,请先停止在更新"); } - var model = parm.Adapt(); - model.Update_by = HttpContextExtension.GetName(HttpContext); + var model = parm.Adapt().ToUpdate(HttpContext); int response = _tasksQzService.UpdateTasks(model); if (response > 0) { diff --git a/ZR.Admin.WebApi/Controllers/System/monitor/UserOnlineLogController.cs b/ZR.Admin.WebApi/Controllers/System/monitor/UserOnlineLogController.cs new file mode 100644 index 00000000..1a0bce42 --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/System/monitor/UserOnlineLogController.cs @@ -0,0 +1,74 @@ +using Microsoft.AspNetCore.Mvc; +using ZR.Admin.WebApi.Filters; +using ZR.ServiceCore.Model.Dto; +using ZR.ServiceCore.Monitor.IMonitorService; + +//创建时间:2024-03-27 +namespace ZR.Admin.WebApi.Controllers +{ + /// + /// 用户在线时长 + /// + [Verify] + [Route("monitor/UserOnlineLog")] + public class UserOnlineLogController : BaseController + { + /// + /// 用户在线时长接口 + /// + private readonly IUserOnlineLogService _UserOnlineLogService; + + public UserOnlineLogController(IUserOnlineLogService UserOnlineLogService) + { + _UserOnlineLogService = UserOnlineLogService; + } + + /// + /// 查询用户在线时长列表 + /// + /// + /// + [HttpGet("list")] + //[ActionPermissionFilter(Permission = "useronlinelog:list")] + public IActionResult QueryUserOnlineLog([FromQuery] UserOnlineLogQueryDto parm) + { + var response = _UserOnlineLogService.GetList(parm); + return SUCCESS(response); + } + + /// + /// 删除用户在线时长 + /// + /// + [HttpDelete("delete/{ids}")] + [ActionPermissionFilter(Permission = "useronlinelog:delete")] + [Log(Title = "用户在线时长", BusinessType = BusinessType.DELETE)] + public IActionResult DeleteUserOnlineLog([FromRoute]string ids) + { + var idArr = Tools.SplitAndConvert(ids); + + return ToResponse(_UserOnlineLogService.Delete(idArr)); + } + + /// + /// 导出用户在线时长 + /// + /// + [Log(Title = "用户在线时长", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)] + [HttpGet("export")] + [ActionPermissionFilter(Permission = "useronlinelog:export")] + public IActionResult Export([FromQuery] UserOnlineLogQueryDto parm) + { + parm.PageNum = 1; + parm.PageSize = 100000; + var list = _UserOnlineLogService.ExportList(parm).Result; + if (list == null || list.Count <= 0) + { + return ToResponse(ResultCode.FAIL, "没有要导出的数据"); + } + var result = ExportExcelMini(list, "用户在线时长", "用户在线时长"); + return ExportExcel(result.Item2, result.Item1); + } + + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Extensions/TasksExtension.cs b/ZR.Admin.WebApi/Extensions/TasksExtension.cs index 80faf6bc..40f44a65 100644 --- a/ZR.Admin.WebApi/Extensions/TasksExtension.cs +++ b/ZR.Admin.WebApi/Extensions/TasksExtension.cs @@ -57,7 +57,7 @@ public static IApplicationBuilder UseAddTaskSchedulers(this IApplicationBuilder /// public static IApplicationBuilder UseInit(this IApplicationBuilder app) { - Console.WriteLine("初始化字典数据..."); + //Console.WriteLine("初始化字典数据..."); var db = DbScoped.SugarScope; var types = db.Queryable() .Where(it => it.Status == "0") diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplIService.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplIService.txt index 8c0333ef..3b56d510 100644 --- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplIService.txt +++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplIService.txt @@ -18,8 +18,9 @@ $if(genTable.TplCategory == "tree") $end ${replaceDto.ModelTypeName} Add${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm); - +$if(replaceDto.ShowBtnEdit) int Update${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm); +$end $if(replaceDto.ShowBtnTruncate) bool Truncate${replaceDto.ModelTypeName}(); $end diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplService.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplService.txt index 5bfc7e4e..dd817ab4 100644 --- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplService.txt +++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/csharp/TplService.txt @@ -104,6 +104,7 @@ $end $end } +$if(replaceDto.ShowBtnEdit) /// /// 修改${genTable.FunctionName} /// @@ -117,6 +118,8 @@ $else return Update(model, true$if(replaceDto.enableLog), "修改${genTable.FunctionName}"$end); $end } + +$end $if(replaceDto.ShowBtnTruncate) /// /// 清空${genTable.FunctionName} @@ -133,7 +136,6 @@ $if(replaceDto.ShowBtnTruncate) return Truncate(); } $end - $if(replaceDto.ShowBtnImport) /// /// 导入${genTable.FunctionName} @@ -167,8 +169,8 @@ $end return (msg, x.ErrorList, x.IgnoreList); } -$end +$end $if(replaceDto.ShowBtnExport) /// /// 导出${genTable.FunctionName} @@ -193,8 +195,8 @@ $end return response; } -$end +$end /// /// 查询导出表达式 /// diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt index d269906d..dae9f789 100644 --- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt +++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt @@ -791,7 +791,11 @@ function handleDelete(row) { const Ids = row.${replaceDto.FistLowerPk} || ids.value proxy - .${confirm}confirm('是否确认删除参数编号为"' + Ids + '"的数据项?') + .${confirm}confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', "警告", { + confirmButtonText: proxy.${t}t('common.ok'), + cancelButtonText: proxy.${t}t('common.cancel'), + type: "warning", + }) .then(function () { return del${genTable.BusinessName}(Ids) }) @@ -807,8 +811,8 @@ $if(replaceDto.ShowBtnTruncate) function handleClear() { proxy .${confirm}confirm("是否确认清空所有数据项?", "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", + confirmButtonText: proxy.${t}t('common.ok'), + cancelButtonText: proxy.${t}t('common.cancel'), type: "warning", }) .then(function () { diff --git a/ZR.Admin.WebApi/wwwroot/data.xlsx b/ZR.Admin.WebApi/wwwroot/data.xlsx index 7fca8b6a..08cd79ee 100644 Binary files a/ZR.Admin.WebApi/wwwroot/data.xlsx and b/ZR.Admin.WebApi/wwwroot/data.xlsx differ diff --git a/ZR.Common/Tools.cs b/ZR.Common/Tools.cs index 2cdaf394..6912daa3 100644 --- a/ZR.Common/Tools.cs +++ b/ZR.Common/Tools.cs @@ -1,4 +1,5 @@ -using System; +using Infrastructure; +using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; @@ -138,5 +139,31 @@ public static bool PasswordStrength(string password) return true; //由数字、字母、符号构成的密码 } + /// + ///生成随机字符串 + /// + ///目标字符串的长度 + ///是否包含数字,1=包含,默认为包含 + ///是否包含小写字母,1=包含,默认为包含 + ///是否包含大写字母,1=包含,默认为包含 + ///是否包含特殊字符,1=包含,默认为不包含 + ///要包含的自定义字符,直接输入要包含的字符列表 + ///指定长度的随机字符串 + public static string GetRandomString(int length, bool useNum, bool useLow, bool useUpp, bool useSpe, string custom) + { + byte[] b = new byte[4]; + System.Security.Cryptography.RandomNumberGenerator.Create().GetBytes(b); + Random r = new(BitConverter.ToInt32(b, 0)); + string s = null, str = custom; + if (useNum == true) { str += "0123456789"; } + if (useLow == true) { str += "abcdefghijklmnopqrstuvwxyz"; } + if (useUpp == true) { str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; } + if (useSpe == true) { str += "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; } + for (int i = 0; i < length; i++) + { + s += str.Substring(r.Next(0, str.Length - 1), 1); + } + return s; + } } } diff --git a/ZR.Repository/BaseRepository.cs b/ZR.Repository/BaseRepository.cs index 97f33099..e2611f53 100644 --- a/ZR.Repository/BaseRepository.cs +++ b/ZR.Repository/BaseRepository.cs @@ -137,7 +137,7 @@ public DbResult UseTran(Action action) /// /// 增删改查方法 /// - public DbResult UseTran(SqlSugarClient client, Action action) + public DbResult UseTran(ISqlSugarClient client, Action action) { try { @@ -159,7 +159,9 @@ public DbResult UseTran(SqlSugarClient client, Action action) /// public bool UseTran2(Action action) { + Console.WriteLine("---事务开始---"); var result = Context.Ado.UseTran(() => action()); + Console.WriteLine("---事务结束---"); return result.IsSuccess; } diff --git a/ZR.Repository/IBaseRepository.cs b/ZR.Repository/IBaseRepository.cs index 2e44a8e5..96f455e4 100644 --- a/ZR.Repository/IBaseRepository.cs +++ b/ZR.Repository/IBaseRepository.cs @@ -36,7 +36,7 @@ namespace ZR.Repository #endregion update DbResult UseTran(Action action); - DbResult UseTran(SqlSugarClient client, Action action); + DbResult UseTran(ISqlSugarClient client, Action action); bool UseTran2(Action action); diff --git a/ZR.ServiceCore/Filters/ActionPermissionFilter.cs b/ZR.ServiceCore/Filters/ActionPermissionFilter.cs index 7c89b793..946b86a1 100644 --- a/ZR.ServiceCore/Filters/ActionPermissionFilter.cs +++ b/ZR.ServiceCore/Filters/ActionPermissionFilter.cs @@ -81,9 +81,13 @@ public override Task OnActionExecutionAsync(ActionExecutingContext context, Acti if (!HasPermi && !Permission.Equals("common")) { logger.Info($"用户{info.UserName}没有权限访问{url},当前权限[{Permission}]"); - JsonResult result = new(new ApiResult((int)ResultCode.FORBIDDEN, $"你当前没有权限访问,请联系管理员", url)) + var apiResult = new ApiResult((int)ResultCode.FORBIDDEN, $"你当前没有权限访问,请联系管理员", url); + apiResult.Put("permi", Permission); + JsonResult result = new(apiResult) { + StatusCode = 403, ContentType = "application/json", + Value = JsonConvert.SerializeObject(apiResult) }; context.HttpContext.Response.StatusCode = 403; context.Result = result; diff --git a/ZR.ServiceCore/Filters/GlobalActionMonitor.cs b/ZR.ServiceCore/Filters/GlobalActionMonitor.cs index 4a986c34..319dddaf 100644 --- a/ZR.ServiceCore/Filters/GlobalActionMonitor.cs +++ b/ZR.ServiceCore/Filters/GlobalActionMonitor.cs @@ -47,7 +47,7 @@ public override Task OnActionExecutionAsync(ActionExecutingContext context, Acti { logger.Info($"请求参数错误,{msg}"); ApiResult response = new((int)ResultCode.PARAM_ERROR, msg); - + context.Result = new JsonResult(response); } return base.OnActionExecutionAsync(context, next); @@ -60,10 +60,10 @@ public override Task OnActionExecutionAsync(ActionExecutingContext context, Acti public override void OnResultExecuted(ResultExecutedContext context) { if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return; - + int statusCode = context.HttpContext.Response.StatusCode; //获得注解信息 LogAttribute logAttribute = GetLogAttribute(controllerActionDescriptor); - if (logAttribute == null) return; + if (logAttribute == null && statusCode != 403) return; try { @@ -111,7 +111,11 @@ public override void OnResultExecuted(ResultExecutedContext context) sysOperLog.OperParam = logAttribute.IsSaveRequestData ? sysOperLog.OperParam : ""; sysOperLog.JsonResult = logAttribute.IsSaveResponseData ? sysOperLog.JsonResult : ""; } - + if (statusCode == 403) + { + sysOperLog.Status = 1; + sysOperLog.ErrorMsg = "无权限访问"; + } LogEventInfo ei = new(NLog.LogLevel.Info, "GlobalActionMonitor", ""); ei.Properties["jsonResult"] = !HttpMethods.IsGet(method) ? jsonResult : ""; diff --git a/ZR.ServiceCore/Model/Article.cs b/ZR.ServiceCore/Model/Article.cs index 6866121c..d42b27a0 100644 --- a/ZR.ServiceCore/Model/Article.cs +++ b/ZR.ServiceCore/Model/Article.cs @@ -1,4 +1,6 @@ -namespace ZR.Model.System +using ZR.ServiceCore.Model.Enums; + +namespace ZR.Model.System { /// /// 文章表 @@ -67,7 +69,7 @@ public class Article /// /// 封面地址 /// - [SugarColumn(ColumnDescription = "封面地址", Length = 255)] + [SugarColumn(ColumnDescription = "封面地址", Length = 5000)] public string CoverUrl { get; set; } /// /// 是否公开 1、公开 0、不公开 @@ -79,11 +81,36 @@ public class Article /// public int IsTop { get; set; } /// + /// 0、文章 1、随笔 2、动态 + /// + [SugarColumn(ColumnDescription = "内容类型0、文章 1、随笔 2、动态", DefaultValue = "0")] + public ArticleTypeEnum ArticleType { get; set; } + /// /// 摘要 /// public string AbstractText { get; set; } [Navigate(NavigateType.OneToOne, nameof(CategoryId), nameof(ArticleCategory.CategoryId))] //自定义关系映射 public ArticleCategory ArticleCategoryNav { get; set; } + /// + /// 评论数 + /// + public int CommentNum { get; set; } + /// + /// 点赞数 + /// + public int PraiseNum { get; set; } + /// + /// 用户IP + /// + public string UserIP { get; set; } + /// + /// 地理位置 + /// + public string Location { get; set; } + /// + /// 手机型号 + /// + public string PhoneModel { get; set; } } } diff --git a/ZR.ServiceCore/Model/Dto/ArticleDto.cs b/ZR.ServiceCore/Model/Dto/ArticleDto.cs index 4d17df77..74e654ea 100644 --- a/ZR.ServiceCore/Model/Dto/ArticleDto.cs +++ b/ZR.ServiceCore/Model/Dto/ArticleDto.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using ZR.Common; namespace ZR.Model.System.Dto { @@ -13,6 +14,11 @@ public class ArticleQueryDto : PagerInfo public int? CategoryId { get; set; } public DateTime? BeginTime { get; set; } public DateTime? EndTime { get; set; } + public int? ArticleType { get; set; } + /// + /// 1、最新 2、私密 3、热门 + /// + public int TabId { get; set; } } /// @@ -22,9 +28,9 @@ public class ArticleDto { [Required(ErrorMessage = "Cid不能为空")] public int Cid { get; set; } - [Required(ErrorMessage = "文章标题不能为空")] + [Required(ErrorMessage = "标题不能为空")] public string Title { get; set; } - [Required(ErrorMessage = "文章内容不能为空")] + [Required(ErrorMessage = "内容不能为空")] public string Content { get; set; } public long? UserId { get; set; } @@ -52,5 +58,45 @@ public class ArticleDto public int IsPublic { get; set; } = 1; public string AbstractText { get; set; } public int IsTop { get; set; } + /// + /// 内容类型 + /// + public int ArticleType { get; set; } + /// + /// 点赞数 + /// + public int PraiseNum { get; set; } + /// + /// 评论数 + /// + public int CommentNum { get; set; } + /// + /// 分享数 + /// + public int ShareNum { get; set; } + /// + /// 用户IP + /// + public string UserIP { get; set; } + /// + /// 地理位置 + /// + public string Location { get; set; } + /// + /// 手机型号 + /// + public string PhoneModel { get; set; } + /// + /// 封面图片集合 + /// + public string[] CoverImgList + { + get + { + return Tools.SplitAndConvert(CoverUrl, ','); + } + } + public string Avatar { get; set; } + public string NickName { get; set; } } } diff --git a/ZR.ServiceCore/Model/Dto/SysDeptDto.cs b/ZR.ServiceCore/Model/Dto/SysDeptDto.cs index ee76ddf8..6e223979 100644 --- a/ZR.ServiceCore/Model/Dto/SysDeptDto.cs +++ b/ZR.ServiceCore/Model/Dto/SysDeptDto.cs @@ -27,5 +27,6 @@ public class SysDeptDto : SysBase public int Status { get; set; } public int DelFlag { get; set; } + public int UserNum { get; set; } } } diff --git a/ZR.ServiceCore/Model/Dto/SysNoticeDto.cs b/ZR.ServiceCore/Model/Dto/SysNoticeDto.cs index e7700647..ffd84964 100644 --- a/ZR.ServiceCore/Model/Dto/SysNoticeDto.cs +++ b/ZR.ServiceCore/Model/Dto/SysNoticeDto.cs @@ -1,3 +1,4 @@ +using MiniExcelLibs.Attributes; using System.ComponentModel.DataAnnotations; namespace ZR.Model.System.Dto @@ -7,13 +8,46 @@ namespace ZR.Model.System.Dto /// public class SysNoticeDto { + //[Required(ErrorMessage = "公告ID不能为空")] + [ExcelColumn(Name = "公告ID")] + [ExcelColumnName("公告ID")] public int NoticeId { get; set; } - [Required] + + [Required(ErrorMessage = "公告标题不能为空")] + [ExcelColumn(Name = "公告标题", Width = 40)] + [ExcelColumnName("公告标题")] public string NoticeTitle { get; set; } + + [Required(ErrorMessage = "公告类型不能为空")] + [ExcelColumn(Name = "公告类型", Ignore = true)] + [ExcelColumnName("公告类型")] public int NoticeType { get; set; } + + [ExcelColumn(Name = "公告内容", Width = 80)] + [ExcelColumnName("公告内容")] public string NoticeContent { get; set; } + + [Required(ErrorMessage = "公告状态 (0正常 1关闭)不能为空")] + [ExcelColumn(Name = "公告状态", Ignore = true)] + [ExcelColumnName("公告状态")] public int Status { get; set; } + + [ExcelColumn(Name = "创建人")] + [ExcelColumnName("创建人")] + public string CreateBy { get; set; } + + [ExcelColumn(Name = "创建时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] + [ExcelColumnName("创建时间")] + public DateTime? CreateTime { get; set; } + + [ExcelColumn(Name = "Remark")] + [ExcelColumnName("Remark")] public string Remark { get; set; } + + [ExcelColumn(Name = "公告类型")] + public string NoticeTypeLabel { get; set; } + [ExcelColumn(Name = "公告状态")] + public string StatusLabel { get; set; } } /// diff --git a/ZR.ServiceCore/Model/Dto/SysOperLogDto.cs b/ZR.ServiceCore/Model/Dto/SysOperLogDto.cs index 36c69378..89c5232e 100644 --- a/ZR.ServiceCore/Model/Dto/SysOperLogDto.cs +++ b/ZR.ServiceCore/Model/Dto/SysOperLogDto.cs @@ -11,11 +11,11 @@ public class SysOperLogQueryDto : PagerInfo /// /// 业务类型 0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据 /// - public int BusinessType { get; set; } = -1; + public int? BusinessType { get; set; } /// /// 状态 /// - public int Status { get; set; } = -1; + public int? Status { get; set; } /// /// 操作模块 /// diff --git a/ZR.ServiceCore/Model/Dto/SysPostDto.cs b/ZR.ServiceCore/Model/Dto/SysPostDto.cs new file mode 100644 index 00000000..521b8ed5 --- /dev/null +++ b/ZR.ServiceCore/Model/Dto/SysPostDto.cs @@ -0,0 +1,20 @@ +using ZR.Model; +using ZR.Model.System; + +namespace ZR.ServiceCore.Model.Dto +{ + public class SysPostDto : SysPost + { + /// + /// 用户个数 + /// + public long UserNum { get; set; } + } + + public class SysPostQueryDto : PagerInfo + { + public string PostName { get; set; } + public string Status { get; set; } + public string PostCode { get; set; } + } +} diff --git a/ZR.ServiceCore/Model/Dto/SysUserDto.cs b/ZR.ServiceCore/Model/Dto/SysUserDto.cs index 0dd2422e..c8e3636f 100644 --- a/ZR.ServiceCore/Model/Dto/SysUserDto.cs +++ b/ZR.ServiceCore/Model/Dto/SysUserDto.cs @@ -8,6 +8,7 @@ public class SysUserDto public string Email { get; set; } public string Remark { get; set; } public string Phonenumber { get; set; } + public string Avatar { get; set; } /// /// 用户性别(0男 1女 2未知) /// @@ -36,6 +37,9 @@ public class SysUserDto /// 岗位集合 /// public int[] PostIds { get; set; } + public string WelcomeContent { get; set; } + public string WelcomeMessage { get; set; } + public bool IsAdmin { get; set; } } public class SysUserQueryDto diff --git a/ZR.ServiceCore/Model/Dto/SysdictDataDto.cs b/ZR.ServiceCore/Model/Dto/SysdictDataDto.cs index 471a3f81..c65eeb49 100644 --- a/ZR.ServiceCore/Model/Dto/SysdictDataDto.cs +++ b/ZR.ServiceCore/Model/Dto/SysdictDataDto.cs @@ -1,11 +1,27 @@ -using System.Collections.Generic; - -namespace ZR.Model.System.Dto +namespace ZR.Model.System.Dto { - public class SysdictDataDto + public class SysdictDataParamDto + { + public string DictType { get; set; } + //public string ColumnName { get; set; } + public List List { get; set; } + } + + public class SysDictDataDto { + public string DictLabel { get; set; } + public string DictValue { get; set; } public string DictType { get; set; } - public string ColumnName { get; set; } - public List List { get; set; } + public string CssClass { get; set; } = string.Empty; + public string ListClass { get; set; } = string.Empty; + /// + /// 多语言翻译key值 + /// + public string LangKey { get; set; } = string.Empty; + + #region uniapp返回字段 + public string Label { get; set; } + public string Value { get; set; } + #endregion } } diff --git a/ZR.ServiceCore/Model/Dto/UploadDto.cs b/ZR.ServiceCore/Model/Dto/UploadDto.cs index a629cbf5..4e1a3218 100644 --- a/ZR.ServiceCore/Model/Dto/UploadDto.cs +++ b/ZR.ServiceCore/Model/Dto/UploadDto.cs @@ -7,15 +7,15 @@ public class UploadDto /// /// 自定文件名 /// - public string? FileName { get; set; } + public string FileName { get; set; } /// /// 存储目录 /// - public string? FileDir { get; set; } + public string FileDir { get; set; } /// /// 文件名生成类型 1 原文件名 2 自定义 3 自动生成 /// public int FileNameType { get; set; } - public IFormFile? File { get; set; } + public IFormFile File { get; set; } } } diff --git a/ZR.ServiceCore/Model/Dto/UserOnlineLogDto.cs b/ZR.ServiceCore/Model/Dto/UserOnlineLogDto.cs new file mode 100644 index 00000000..03b8e296 --- /dev/null +++ b/ZR.ServiceCore/Model/Dto/UserOnlineLogDto.cs @@ -0,0 +1,70 @@ + +using MiniExcelLibs.Attributes; +using System.ComponentModel.DataAnnotations; +using ZR.Model; + +namespace ZR.ServiceCore.Model.Dto +{ + /// + /// 用户在线时长查询对象 + /// + public class UserOnlineLogQueryDto : PagerInfo + { + public int? UserId { get; set; } + public string UserIP { get; set; } + public DateTime? BeginAddTime { get; set; } + public DateTime? EndAddTime { get; set; } + } + + /// + /// 用户在线时长输入输出对象 + /// + public class UserOnlineLogDto + { + [Required(ErrorMessage = "Id不能为空")] + [ExcelColumn(Name = "Id")] + [ExcelColumnName("Id")] + [JsonConverter(typeof(ValueToStringConverter))] + public long Id { get; set; } + + [Required(ErrorMessage = "用户id不能为空")] + [ExcelColumn(Name = "用户id")] + [ExcelColumnName("用户id")] + public long UserId { get; set; } + + [Required(ErrorMessage = "在线时长(分)不能为空")] + [ExcelColumn(Name = "在线时长(分)")] + [ExcelColumnName("在线时长(分)")] + public double OnlineTime { get; set; } + + [ExcelColumn(Name = "结束时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] + [ExcelColumnName("结束时间")] + public DateTime? AddTime { get; set; } + + [ExcelColumn(Name = "地址位置")] + [ExcelColumnName("地址位置")] + public string Location { get; set; } + + [ExcelColumn(Name = "用户IP")] + [ExcelColumnName("用户IP")] + public string UserIP { get; set; } + + [ExcelColumn(Name = "备注")] + [ExcelColumnName("备注")] + public string Remark { get; set; } + + [ExcelColumn(Name = "登录时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] + [ExcelColumnName("登录时间")] + public DateTime? LoginTime { get; set; } + + [ExcelColumn(Name = "今日在线时长")] + [ExcelColumnName("今日在线时长")] + public string TodayOnlineTime { get; set; } + + [ExcelColumn(Name = "登录平台")] + [ExcelColumnName("登录平台")] + public string Platform { get; set; } + [ExcelColumn(Name = "用户昵称")] + public string NickName { get; set; } + } +} \ No newline at end of file diff --git a/ZR.ServiceCore/Model/Enums/ArticleTypeEnum.cs b/ZR.ServiceCore/Model/Enums/ArticleTypeEnum.cs new file mode 100644 index 00000000..40af09e5 --- /dev/null +++ b/ZR.ServiceCore/Model/Enums/ArticleTypeEnum.cs @@ -0,0 +1,9 @@ +namespace ZR.ServiceCore.Model.Enums +{ + public enum ArticleTypeEnum + { + Article = 0, + Essay = 1, + Monent = 2, + } +} diff --git a/ZR.ServiceCore/Model/SqlDiffLog.cs b/ZR.ServiceCore/Model/SqlDiffLog.cs index 0b642778..9a61de99 100644 --- a/ZR.ServiceCore/Model/SqlDiffLog.cs +++ b/ZR.ServiceCore/Model/SqlDiffLog.cs @@ -1,6 +1,6 @@ namespace ZR.Model.System { - [SugarTable("SqlDiffLog", "数据差异日志")] + [SugarTable("sqlDiffLog", "数据差异日志")] [Tenant("0")] public class SqlDiffLog { diff --git a/ZR.ServiceCore/Model/SysOperLog.cs b/ZR.ServiceCore/Model/SysOperLog.cs index 3eed2894..84704323 100644 --- a/ZR.ServiceCore/Model/SysOperLog.cs +++ b/ZR.ServiceCore/Model/SysOperLog.cs @@ -1,7 +1,4 @@ using MiniExcelLibs.Attributes; -using SqlSugar; -using System; -using System.ComponentModel; namespace ZR.Model.System { @@ -90,6 +87,7 @@ public class SysOperLog /// /// 错误消息 /// + [SugarColumn(Length = 4000)] public string ErrorMsg { get; set; } /// diff --git a/ZR.ServiceCore/Model/SysRoleDept.cs b/ZR.ServiceCore/Model/SysRoleDept.cs index 168d048b..14abb4b4 100644 --- a/ZR.ServiceCore/Model/SysRoleDept.cs +++ b/ZR.ServiceCore/Model/SysRoleDept.cs @@ -9,7 +9,7 @@ public class SysRoleDept [SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL, IsPrimaryKey = true)] public long RoleId { get; set; } - [SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL, IsPrimaryKey = true)] + [SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL, IsPrimaryKey = false)] public long DeptId { get; set; } } } diff --git a/ZR.ServiceCore/Model/SysUser.cs b/ZR.ServiceCore/Model/SysUser.cs index 01e9dbc1..5ec96655 100644 --- a/ZR.ServiceCore/Model/SysUser.cs +++ b/ZR.ServiceCore/Model/SysUser.cs @@ -81,15 +81,15 @@ public class SysUser : SysBase public string Province { get; set; } public string City { get; set; } #region 表额外字段 - public bool IsAdmin() - { - return IsAdmin(UserId); - } - public static bool IsAdmin(long userId) + + [SugarColumn(IsIgnore = true)] + public bool IsAdmin { - return 1 == userId; + get + { + return UserId == 1; + } } - /// /// 拥有角色个数 /// diff --git a/ZR.ServiceCore/Model/SysUserRole.cs b/ZR.ServiceCore/Model/SysUserRole.cs index c1570dc9..aaacae2a 100644 --- a/ZR.ServiceCore/Model/SysUserRole.cs +++ b/ZR.ServiceCore/Model/SysUserRole.cs @@ -1,13 +1,11 @@ -using SqlSugar; - -namespace ZR.Model.System +namespace ZR.Model.System { /// /// 用户角色关联表 用户N-1 角色 /// [SugarTable("sys_user_role", "用户和角色关联表")] [Tenant("0")] - public class SysUserRole + public class SysUserRole : SysBase { [SugarColumn(ColumnName = "user_id", IsPrimaryKey = true)] public long UserId { get; set; } diff --git a/ZR.ServiceCore/Model/UserOnlineLog.cs b/ZR.ServiceCore/Model/UserOnlineLog.cs new file mode 100644 index 00000000..73e7f19c --- /dev/null +++ b/ZR.ServiceCore/Model/UserOnlineLog.cs @@ -0,0 +1,55 @@ + +namespace ZR.ServiceCore.Model +{ + /// + /// 用户在线时长 + /// + [SugarTable("userOnlineLog", TableDescription = "用户在线时长")] + [Tenant("0")] + public class UserOnlineLog + { + /// + /// Id + /// + [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] + public long Id { get; set; } + + /// + /// 用户id + /// + public long UserId { get; set; } + + /// + /// 在线时长(分) + /// + public double OnlineTime { get; set; } + /// + /// 今日在线时长 + /// + public double TodayOnlineTime { get; set; } + + /// + /// 结束时间 + /// + public DateTime? AddTime { get; set; } + + /// + /// 地址位置 + /// + public string Location { get; set; } + + /// + /// 用户IP + /// + public string UserIP { get; set; } + public DateTime LoginTime { get; set; } + /// + /// 备注 + /// + public string Remark { get; set; } + /// + /// 登录平台 + /// + public string Platform { get; set; } + } +} \ No newline at end of file diff --git a/ZR.ServiceCore/Services/ArticleService.cs b/ZR.ServiceCore/Services/ArticleService.cs index 8ece68bd..cd3b01ea 100644 --- a/ZR.ServiceCore/Services/ArticleService.cs +++ b/ZR.ServiceCore/Services/ArticleService.cs @@ -3,6 +3,7 @@ using ZR.Model.System; using ZR.Model.System.Dto; using ZR.Repository; +using ZR.ServiceCore.Model.Enums; namespace ZR.ServiceCore.Services { @@ -26,6 +27,7 @@ public PagedInfo GetList(ArticleQueryDto parm) predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Status), m => m.Status == parm.Status); predicate = predicate.AndIF(parm.IsPublic != null, m => m.IsPublic == parm.IsPublic); predicate = predicate.AndIF(parm.IsTop != null, m => m.IsTop == parm.IsTop); + predicate = predicate.AndIF(parm.ArticleType != null, m => (int)m.ArticleType == parm.ArticleType); if (parm.CategoryId != null) { @@ -56,8 +58,9 @@ public PagedInfo GetHotList(ArticleQueryDto parm) predicate = predicate.And(m => m.Status == "1"); predicate = predicate.And(m => m.IsPublic == 1); predicate = predicate.AndIF(parm.IsTop != null, m => m.IsTop == parm.IsTop); - + predicate = predicate.And(m => (int)m.ArticleType == parm.ArticleType); predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Title), m => m.Title.Contains(parm.Title)); + if (parm.CategoryId != null) { var allChildCategory = Context.Queryable() @@ -69,8 +72,42 @@ public PagedInfo GetHotList(ArticleQueryDto parm) var response = Queryable() .IgnoreColumns(x => new { x.Content }) .Includes(x => x.ArticleCategoryNav) + .LeftJoin((m, u) => m.UserId == u.UserId).Filter(null, true) .Where(predicate.ToExpression()) - .ToPage(parm); + .OrderByDescending(m => m.Cid) + .Select((m, u) => new ArticleDto() + { + Avatar = u.Avatar, + NickName = u.NickName + }, true) + .ToPage(parm); + + return response; + } + + /// + /// 前台查询动态列表 + /// + /// + /// + public PagedInfo GetArticleList(ArticleQueryDto parm) + { + var predicate = Expressionable.Create
(); + predicate = predicate.And(m => m.Status == "1"); + predicate = predicate.And(m => m.IsPublic == 1); + predicate = predicate.And(m => m.ArticleType == ArticleTypeEnum.Monent); + + var response = Queryable() + .LeftJoin((m, u) => m.UserId == u.UserId).Filter(null, true) + .Where(predicate.ToExpression()) + .OrderByIF(parm.TabId == 3, m => new { m.PraiseNum }, OrderByType.Desc) + .OrderBy(m => m.Cid, OrderByType.Desc) + .Select((m, u) => new ArticleDto() + { + Avatar = u.Avatar, + NickName = u.NickName + }, true) + .ToPage(parm); return response; } @@ -89,12 +126,20 @@ public PagedInfo GetMyList(ArticleQueryDto parm) predicate = predicate.AndIF(parm.BeginTime != null, m => m.CreateTime >= parm.BeginTime); predicate = predicate.AndIF(parm.EndTime != null, m => m.CreateTime <= parm.EndTime); predicate = predicate.And(m => m.UserId == parm.UserId); + predicate = predicate.AndIF(parm.ArticleType != null, m => (int)m.ArticleType == parm.ArticleType); + predicate = predicate.AndIF(parm.TabId == 2, m => m.IsPublic == 0 && m.UserId == parm.UserId); var response = Queryable() - .IgnoreColumns(x => new { x.Content }) + //.IgnoreColumns(x => new { x.Content }) .Includes(x => x.ArticleCategoryNav) .Where(predicate.ToExpression()) - .ToPage(parm); + .OrderByIF(parm.TabId == 3, m => new { m.PraiseNum }, OrderByType.Desc) + .OrderByDescending(m => m.Cid) + .Select((x) => new ArticleDto() + { + Content = x.ArticleType == 0 ? string.Empty : x.Content, + }, true) + .ToPage(parm); return response; } @@ -163,5 +208,18 @@ public int UpdateArticleHit(int cid) .ExecuteCommand(); return response; } + + /// + /// 点赞 + /// + /// + /// + public int PraiseArticle(int cid) + { + return Context.Updateable
() + .SetColumns(it => it.PraiseNum == it.PraiseNum + 1) + .Where(it => it.Cid == cid) + .ExecuteCommand(); + } } } diff --git a/ZR.ServiceCore/Services/GenTableService.cs b/ZR.ServiceCore/Services/GenTableService.cs index 4484cd27..2d21795f 100644 --- a/ZR.ServiceCore/Services/GenTableService.cs +++ b/ZR.ServiceCore/Services/GenTableService.cs @@ -159,7 +159,7 @@ public bool SynchDb(long tableId, GenTable genTable, List dbTabl updateColumns.Add(column); } } - bool result = UseTran2(() => + var result = UseTran(() => { if (insertColumns.Count > 0) { @@ -176,7 +176,7 @@ public bool SynchDb(long tableId, GenTable genTable, List dbTabl GenTableColumnService.Delete(delColumns.Select(f => f.ColumnId).ToList()); } }); - return result; + return result.IsSuccess; } } diff --git a/ZR.ServiceCore/Services/IService/IArticleService.cs b/ZR.ServiceCore/Services/IService/IArticleService.cs index db1d7952..57138a68 100644 --- a/ZR.ServiceCore/Services/IService/IArticleService.cs +++ b/ZR.ServiceCore/Services/IService/IArticleService.cs @@ -15,8 +15,10 @@ public interface IArticleService : IBaseService
/// public int UpdateArticle(Article model); PagedInfo GetHotList(ArticleQueryDto parm); + PagedInfo GetArticleList(ArticleQueryDto parm); int TopArticle(Article model); int ChangeArticlePublic(Article model); int UpdateArticleHit(int cid); + int PraiseArticle(int cid); } } diff --git a/ZR.ServiceCore/Services/IService/ISysDeptService.cs b/ZR.ServiceCore/Services/IService/ISysDeptService.cs index 44b04328..7d9186ea 100644 --- a/ZR.ServiceCore/Services/IService/ISysDeptService.cs +++ b/ZR.ServiceCore/Services/IService/ISysDeptService.cs @@ -7,6 +7,7 @@ namespace ZR.ServiceCore.Services { public interface ISysDeptService : IBaseService { + List GetList(SysDeptQueryDto dept); List GetSysDepts(SysDeptQueryDto dept); string CheckDeptNameUnique(SysDept dept); int InsertDept(SysDept dept); diff --git a/ZR.ServiceCore/Services/IService/ISysDictDataService.cs b/ZR.ServiceCore/Services/IService/ISysDictDataService.cs index 2fa22ca1..5afa4bf9 100644 --- a/ZR.ServiceCore/Services/IService/ISysDictDataService.cs +++ b/ZR.ServiceCore/Services/IService/ISysDictDataService.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; -using ZR.Model; +using ZR.Model; using ZR.Model.System; +using ZR.Model.System.Dto; namespace ZR.ServiceCore.Services { @@ -8,12 +8,12 @@ public interface ISysDictDataService : IBaseService { public PagedInfo SelectDictDataList(SysDictData dictData, PagerInfo pagerInfo); public List SelectDictDataByType(string dictType); - public List SelectDictDataByTypes(string[] dictTypes); + public List SelectDictDataByTypes(string[] dictTypes); public SysDictData SelectDictDataById(long dictCode); public long InsertDictData(SysDictData dict); public long UpdateDictData(SysDictData dict); public int DeleteDictDataByIds(long[] dictCodes); int UpdateDictDataType(string old_dictType, string new_dictType); - List SelectDictDataByCustomSql(SysDictType sysDictType); + List SelectDictDataByCustomSql(SysDictType sysDictType); } } diff --git a/ZR.ServiceCore/Services/IService/ISysDictService.cs b/ZR.ServiceCore/Services/IService/ISysDictService.cs index 1da71606..373155af 100644 --- a/ZR.ServiceCore/Services/IService/ISysDictService.cs +++ b/ZR.ServiceCore/Services/IService/ISysDictService.cs @@ -1,5 +1,6 @@ using ZR.Model; using ZR.Model.System; +using ZR.Model.System.Dto; namespace ZR.ServiceCore.Services { @@ -46,6 +47,6 @@ public interface ISysDictService /// SysDictType GetInfo(long dictId); - List SelectDictDataByCustomSql(string dictType); + List SelectDictDataByCustomSql(string dictType); } } diff --git a/ZR.ServiceCore/Services/IService/ISysNoticeService.cs b/ZR.ServiceCore/Services/IService/ISysNoticeService.cs index c6cd3980..8e041827 100644 --- a/ZR.ServiceCore/Services/IService/ISysNoticeService.cs +++ b/ZR.ServiceCore/Services/IService/ISysNoticeService.cs @@ -15,5 +15,6 @@ public interface ISysNoticeService : IBaseService List GetSysNotices(); PagedInfo GetPageList(SysNoticeQueryDto parm); + PagedInfo ExportList(SysNoticeQueryDto parm); } } diff --git a/ZR.ServiceCore/Services/IService/IUserOnlineLogService.cs b/ZR.ServiceCore/Services/IService/IUserOnlineLogService.cs new file mode 100644 index 00000000..0a5e7318 --- /dev/null +++ b/ZR.ServiceCore/Services/IService/IUserOnlineLogService.cs @@ -0,0 +1,18 @@ +using ZR.Model; +using ZR.ServiceCore.Model; +using ZR.ServiceCore.Model.Dto; + +namespace ZR.ServiceCore.Monitor.IMonitorService +{ + /// + /// 用户在线时长service接口 + /// + public interface IUserOnlineLogService : IBaseService + { + PagedInfo GetList(UserOnlineLogQueryDto parm); + + UserOnlineLog AddUserOnlineLog(UserOnlineLog parm); + + PagedInfo ExportList(UserOnlineLogQueryDto parm); + } +} diff --git a/ZR.ServiceCore/Services/SeedDataService.cs b/ZR.ServiceCore/Services/SeedDataService.cs index e8a01421..70fb6331 100644 --- a/ZR.ServiceCore/Services/SeedDataService.cs +++ b/ZR.ServiceCore/Services/SeedDataService.cs @@ -221,6 +221,24 @@ public class SeedDataService return (msg, x.ErrorList, x.IgnoreList); } + /// + /// 公告数据 + /// + /// + /// + public (string, object, object) InitNoticeData(List data) + { + var db = DbScoped.SugarScope; + var x = db.Storageable(data) + .WhereColumns(it => new { it.NoticeId }) + .ToStorage(); + x.AsInsertable.ExecuteCommand(); + x.AsUpdateable.ExecuteCommand(); + + string msg = $"[通知公告数据] 插入{x.InsertList.Count} 更新{x.UpdateList.Count} 错误{x.ErrorList.Count} 总共{x.TotalList.Count}"; + return (msg, x.ErrorList, x.IgnoreList); + } + /// /// 初始化种子数据 /// @@ -243,6 +261,7 @@ public List InitSeedData(string path, bool clean) db.DbMaintenance.TruncateTable(); db.DbMaintenance.TruncateTable(); db.DbMaintenance.TruncateTable(); + db.DbMaintenance.TruncateTable(); } var sysUser = MiniExcel.Query(path, sheetName: "user").ToList(); @@ -289,6 +308,10 @@ public List InitSeedData(string path, bool clean) var result11 = InitArticleCategoryData(sysArticleCategory); result.Add(result11.Item1); + var sysNotice = MiniExcel.Query(path, sheetName: "notice").ToList(); + var result12 = InitNoticeData(sysNotice); + result.Add(result12.Item1); + return result; } } diff --git a/ZR.ServiceCore/Services/SysDeptService.cs b/ZR.ServiceCore/Services/SysDeptService.cs index 475f978b..11b2fa33 100644 --- a/ZR.ServiceCore/Services/SysDeptService.cs +++ b/ZR.ServiceCore/Services/SysDeptService.cs @@ -18,7 +18,28 @@ public SysDeptService(ISysRoleDeptService roleDeptRepository) { RoleDeptRepository = roleDeptRepository; } + /// + /// 查询部门管理数据 + /// + /// + /// + public List GetList(SysDeptQueryDto dept) + { + var predicate = Expressionable.Create(); + predicate = predicate.And(it => it.DelFlag == 0); + predicate = predicate.AndIF(dept.DeptName.IfNotEmpty(), it => it.DeptName.Contains(dept.DeptName)); + predicate = predicate.AndIF(dept.Status != null, it => it.Status == dept.Status); + var response = Queryable() + .Where(predicate.ToExpression()) + .Select((it) => new SysDeptDto() + { + UserNum = SqlFunc.Subqueryable().Where(f => f.DeptId == it.DeptId).Count() + }, true) + .ToList(); + + return response; + } /// /// 查询部门管理数据 /// @@ -31,7 +52,7 @@ public List GetSysDepts(SysDeptQueryDto dept) predicate = predicate.AndIF(dept.DeptName.IfNotEmpty(), it => it.DeptName.Contains(dept.DeptName)); predicate = predicate.AndIF(dept.Status != null, it => it.Status == dept.Status); - var response = GetList(predicate.ToExpression()); + var response = Queryable().Where(predicate.ToExpression()).ToList(); return response; } diff --git a/ZR.ServiceCore/Services/SysDictDataService.cs b/ZR.ServiceCore/Services/SysDictDataService.cs index e07449b3..dcb5d701 100644 --- a/ZR.ServiceCore/Services/SysDictDataService.cs +++ b/ZR.ServiceCore/Services/SysDictDataService.cs @@ -2,6 +2,7 @@ using ZR.Common; using ZR.Model; using ZR.Model.System; +using ZR.Model.System.Dto; namespace ZR.ServiceCore.Services { @@ -44,7 +45,7 @@ public List SelectDictDataByType(string dictType) return list; } - public List SelectDictDataByTypes(string[] dictTypes) + public List SelectDictDataByTypes(string[] dictTypes) { string CK = $"SelectDictDataByTypes_{dictTypes}"; @@ -52,6 +53,11 @@ public List SelectDictDataByTypes(string[] dictTypes) .WithCache(CK, 60 * 30) .Where(f => f.Status == "0" && dictTypes.Contains(f.DictType)) .OrderBy(it => it.DictSort) + .Select((it) => new SysDictDataDto() + { + Label = it.DictLabel, + Value = it.DictValue + }, true) .ToList(); return list; @@ -136,9 +142,9 @@ public int UpdateDictDataType(string old_dictType, string new_dictType) ///
/// /// - public List SelectDictDataByCustomSql(SysDictType sysDictType) + public List SelectDictDataByCustomSql(SysDictType sysDictType) { - return Context.Ado.SqlQuery(sysDictType?.CustomSql).ToList(); + return Context.Ado.SqlQuery(sysDictType?.CustomSql).ToList(); } } } diff --git a/ZR.ServiceCore/Services/SysDictService.cs b/ZR.ServiceCore/Services/SysDictService.cs index 9d227224..ac0c08d3 100644 --- a/ZR.ServiceCore/Services/SysDictService.cs +++ b/ZR.ServiceCore/Services/SysDictService.cs @@ -2,6 +2,7 @@ using Infrastructure.Attribute; using ZR.Model; using ZR.Model.System; +using ZR.Model.System.Dto; namespace ZR.ServiceCore.Services { @@ -120,7 +121,7 @@ public SysDictType GetInfo(long dictId) ///
/// /// - public List SelectDictDataByCustomSql(string dictType) + public List SelectDictDataByCustomSql(string dictType) { var dictInfo = Queryable() .Where(f => f.DictType == dictType).First(); diff --git a/ZR.ServiceCore/Services/SysNoticeService.cs b/ZR.ServiceCore/Services/SysNoticeService.cs index 83de077a..729168a0 100644 --- a/ZR.ServiceCore/Services/SysNoticeService.cs +++ b/ZR.ServiceCore/Services/SysNoticeService.cs @@ -2,6 +2,7 @@ using ZR.Model; using ZR.Model.System; using ZR.Model.System.Dto; +using ZR.Repository; namespace ZR.ServiceCore.Services { @@ -14,8 +15,6 @@ namespace ZR.ServiceCore.Services [AppService(ServiceType = typeof(ISysNoticeService), ServiceLifetime = LifeTime.Transient)] public class SysNoticeService : BaseService, ISysNoticeService { - #region 业务逻辑代码 - /// /// 查询系统通知 /// @@ -32,17 +31,45 @@ public List GetSysNotices() } public PagedInfo GetPageList(SysNoticeQueryDto parm) + { + var predicate = QueryExp(parm); + var response = GetPages(predicate.ToExpression(), parm); + return response; + } + + /// + /// 导出通知公告表 + /// + /// + /// + public PagedInfo ExportList(SysNoticeQueryDto parm) { - var predicate = Expressionable.Create(); + var predicate = QueryExp(parm); + var response = Queryable() + .Where(predicate.ToExpression()) + .Select((it) => new SysNoticeDto() + { + NoticeTypeLabel = it.NoticeType.GetConfigValue("sys_notice_type"), + StatusLabel = it.Status.GetConfigValue("sys_notice_status"), + }, true) + .ToPage(parm); + + return response; + } + /// + /// 查询导出表达式 + /// + /// + /// + private static Expressionable QueryExp(SysNoticeQueryDto parm) + { + var predicate = Expressionable.Create(); predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.NoticeTitle), m => m.NoticeTitle.Contains(parm.NoticeTitle)); predicate = predicate.AndIF(parm.NoticeType != null, m => m.NoticeType == parm.NoticeType); predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.CreateBy), m => m.Create_by.Contains(parm.CreateBy) || m.Update_by.Contains(parm.CreateBy)); predicate = predicate.AndIF(parm.Status != null, m => m.Status == parm.Status); - var response = GetPages(predicate.ToExpression(), parm); - return response; + return predicate; } - - #endregion } } \ No newline at end of file diff --git a/ZR.ServiceCore/Services/SysOperLogService.cs b/ZR.ServiceCore/Services/SysOperLogService.cs index 48c1b55f..71f22b1a 100644 --- a/ZR.ServiceCore/Services/SysOperLogService.cs +++ b/ZR.ServiceCore/Services/SysOperLogService.cs @@ -18,7 +18,7 @@ public class SysOperLogService : BaseService, ISysOperLogService /// 日志对象 public void InsertOperlog(SysOperLog operLog) { - if (operLog.OperParam.Length >= 1000) + if (operLog.OperParam != null && operLog.OperParam.Length >= 1000) { operLog.OperParam = operLog.OperParam[..1000]; } @@ -38,8 +38,8 @@ public PagedInfo SelectOperLogList(SysOperLogQueryDto sysOper) exp.AndIF(sysOper.BeginTime != null, it => it.OperTime >= sysOper.BeginTime && it.OperTime <= sysOper.EndTime); exp.AndIF(sysOper.Title.IfNotEmpty(), it => it.Title.Contains(sysOper.Title)); exp.AndIF(sysOper.OperName.IfNotEmpty(), it => it.OperName.Contains(sysOper.OperName)); - exp.AndIF(sysOper.BusinessType != -1, it => it.BusinessType == sysOper.BusinessType); - exp.AndIF(sysOper.Status != -1, it => it.Status == sysOper.Status); + exp.AndIF(sysOper.BusinessType != null, it => it.BusinessType == sysOper.BusinessType); + exp.AndIF(sysOper.Status != null, it => it.Status == sysOper.Status); exp.AndIF(sysOper.OperParam != null, it => it.OperParam.Contains(sysOper.OperParam)); return Queryable() diff --git a/ZR.ServiceCore/Services/SysPermissionService.cs b/ZR.ServiceCore/Services/SysPermissionService.cs index fc06f155..c31b5b52 100644 --- a/ZR.ServiceCore/Services/SysPermissionService.cs +++ b/ZR.ServiceCore/Services/SysPermissionService.cs @@ -30,7 +30,7 @@ public List GetRolePermission(SysUser user) { List roles = new(); // 管理员拥有所有权限 - if (user.IsAdmin()) + if (user.IsAdmin) { roles.Add("admin"); } @@ -50,7 +50,7 @@ public List GetMenuPermission(SysUser user) { List perms = new(); // 管理员拥有所有权限 - if (user.IsAdmin() || GetRolePermission(user).Exists(f => f.Equals(GlobalConstant.AdminRole))) + if (user.IsAdmin || GetRolePermission(user).Exists(f => f.Equals(GlobalConstant.AdminRole))) { perms.Add(GlobalConstant.AdminPerm); } diff --git a/ZR.ServiceCore/Services/SysRoleService.cs b/ZR.ServiceCore/Services/SysRoleService.cs index 53868533..6280260b 100644 --- a/ZR.ServiceCore/Services/SysRoleService.cs +++ b/ZR.ServiceCore/Services/SysRoleService.cs @@ -177,7 +177,7 @@ public int DeleteRoleMenuByRoleId(long roleId) /// public bool AuthDataScope(SysRoleDto sysRoleDto) { - return UseTran2(() => + var result = UseTran(() => { //删除角色菜单 //DeleteRoleMenuByRoleId(sysRoleDto.RoleId); @@ -194,10 +194,11 @@ public bool AuthDataScope(SysRoleDto sysRoleDto) RoleMenuService.DeleteRoleMenuByRoleIdMenuIds(sysRoleDto.RoleId, delMenuIds); sysRoleDto.MenuIds = addMenuIds.ToList(); - sysRoleDto.DelMenuIds= delMenuIds.ToList(); + sysRoleDto.DelMenuIds = delMenuIds.ToList(); InsertRoleMenu(sysRoleDto); Console.WriteLine($"减少了{delMenuIds.Length},增加了{addMenuIds.Length}菜单"); }); + return result.IsSuccess; } #region Service diff --git a/ZR.ServiceCore/Services/SysUserService.cs b/ZR.ServiceCore/Services/SysUserService.cs index 4dd270e3..ab05f748 100644 --- a/ZR.ServiceCore/Services/SysUserService.cs +++ b/ZR.ServiceCore/Services/SysUserService.cs @@ -71,7 +71,7 @@ public PagedInfo SelectUserList(SysUserQueryDto user, PagerInfo pager) public SysUser SelectUserById(long userId) { var user = Queryable().Filter(null, true).WithCache(60 * 5) - .Where(f => f.UserId == userId).First(); + .Where(f => f.UserId == userId && f.DelFlag == 0).First(); if (user != null && user.UserId > 0) { user.Roles = RoleService.SelectUserRoleListByUserId(userId); @@ -127,7 +127,7 @@ public int UpdateUser(SysUser user) var roleIds = RoleService.SelectUserRoles(user.UserId); var diffArr = roleIds.Where(c => !((IList)user.RoleIds).Contains(c)).ToArray(); var diffArr2 = user.RoleIds.Where(c => !((IList)roleIds).Contains(c)).ToArray(); - bool result = UseTran2(() => + var result = UseTran(() => { if (diffArr.Length > 0 || diffArr2.Length > 0) { @@ -142,7 +142,7 @@ public int UpdateUser(SysUser user) UserPostService.InsertUserPost(user); ChangeUser(user); }); - return result ? 1 : 0; + return result.IsSuccess ? 1 : 0; } public int ChangeUser(SysUser user) @@ -193,11 +193,15 @@ public int ChangeUserStatus(SysUser user) public int DeleteUser(long userid) { CheckUserAllowed(new SysUser() { UserId = userid }); - //删除用户与角色关联 - UserRoleService.DeleteUserRoleByUserId((int)userid); - // 删除用户与岗位关联 - UserPostService.Delete(userid); - return Update(new SysUser() { UserId = userid, DelFlag = 2 }, it => new { it.DelFlag }, f => f.UserId == userid); + var result = UseTran(() => + { + //删除用户与角色关联 + UserRoleService.DeleteUserRoleByUserId((int)userid); + // 删除用户与岗位关联 + UserPostService.Delete(userid); + Update(new SysUser() { UserId = userid, DelFlag = 2 }, it => new { it.DelFlag }, f => f.UserId == userid); + }); + return result.IsSuccess ? 1 : 0; } /// @@ -254,7 +258,7 @@ public SysUser Register(RegisterDto dto) /// public void CheckUserAllowed(SysUser user) { - if (user.IsAdmin()) + if (user.IsAdmin) { throw new CustomException("不允许操作超级管理员角色"); } @@ -267,12 +271,6 @@ public void CheckUserAllowed(SysUser user) /// public void CheckUserDataScope(long userid, long loginUserId) { - if (!SysUser.IsAdmin(loginUserId)) - { - SysUser user = new SysUser() { UserId = userid }; - - //TODO 判断用户是否有数据权限 - } } /// @@ -329,7 +327,7 @@ public void CheckUserDataScope(long userid, long loginUserId) /// public SysUser Login(LoginBodyDto user) { - return GetFirst(it => it.UserName == user.Username && it.Password.ToLower() == user.Password.ToLower()); + return GetFirst(it => it.UserName == user.Username && it.Password.ToLower() == user.Password.ToLower() && it.DelFlag == 0); } /// diff --git a/ZR.ServiceCore/Services/UserOnlineLogService.cs b/ZR.ServiceCore/Services/UserOnlineLogService.cs new file mode 100644 index 00000000..1566b30c --- /dev/null +++ b/ZR.ServiceCore/Services/UserOnlineLogService.cs @@ -0,0 +1,88 @@ +using Infrastructure.Attribute; +using ZR.Model; +using ZR.Model.System; +using ZR.Repository; +using ZR.ServiceCore.Model; +using ZR.ServiceCore.Model.Dto; +using ZR.ServiceCore.Monitor.IMonitorService; + +namespace ZR.ServiceCore.Monitor +{ + /// + /// 用户在线时长Service业务层处理 + /// + [AppService(ServiceType = typeof(IUserOnlineLogService), ServiceLifetime = LifeTime.Transient)] + public class UserOnlineLogService : BaseService, IUserOnlineLogService + { + /// + /// 查询用户在线时长列表 + /// + /// + /// + public PagedInfo GetList(UserOnlineLogQueryDto parm) + { + var predicate = QueryExp(parm); + + var response = Queryable() + //.OrderBy("Id desc") + .Where(predicate.ToExpression()) + .LeftJoin((it, u) => it.UserId == u.UserId) + .Select((it, u) => new UserOnlineLogDto() + { + NickName = u.NickName + }, true) + .ToPage(parm); + + return response; + } + + /// + /// 添加用户在线时长 + /// + /// + /// + public UserOnlineLog AddUserOnlineLog(UserOnlineLog model) + { + if (model.OnlineTime >= 0.5) + { + Insertable(model).ExecuteReturnSnowflakeId(); + } + return model; + } + + /// + /// 导出用户在线时长 + /// + /// + /// + public PagedInfo ExportList(UserOnlineLogQueryDto parm) + { + var predicate = QueryExp(parm); + + var response = Queryable() + .Where(predicate.ToExpression()) + .Select((it) => new UserOnlineLogDto() + { + }, true) + .ToPage(parm); + + return response; + } + + /// + /// 查询导出表达式 + /// + /// + /// + private static Expressionable QueryExp(UserOnlineLogQueryDto parm) + { + var predicate = Expressionable.Create(); + + predicate = predicate.AndIF(parm.UserId != null, it => it.UserId == parm.UserId); + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.UserIP), it => it.UserIP == parm.UserIP); + predicate = predicate.AndIF(parm.BeginAddTime == null, it => it.AddTime >= DateTime.Now.ToShortDateString().ParseToDateTime()); + predicate = predicate.AndIF(parm.BeginAddTime != null, it => it.AddTime >= parm.BeginAddTime); + return predicate; + } + } +} \ No newline at end of file diff --git a/ZR.ServiceCore/Signalr/MessageHub.cs b/ZR.ServiceCore/Signalr/MessageHub.cs index a21d728a..a3e73dd0 100644 --- a/ZR.ServiceCore/Signalr/MessageHub.cs +++ b/ZR.ServiceCore/Signalr/MessageHub.cs @@ -6,6 +6,7 @@ using System.Web; using UAParser; using ZR.ServiceCore.Model.Dto; +using ZR.ServiceCore.Monitor.IMonitorService; using ZR.ServiceCore.Services; namespace ZR.ServiceCore.Signalr @@ -21,11 +22,13 @@ public class MessageHub : Hub //private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private readonly ISysNoticeService SysNoticeService; private readonly ISysUserService UserService; + private readonly IUserOnlineLogService UserOnlineLogService; - public MessageHub(ISysNoticeService noticeService, ISysUserService userService) + public MessageHub(ISysNoticeService noticeService, ISysUserService userService, IUserOnlineLogService userOnlineLogService) { SysNoticeService = noticeService; UserService = userService; + UserOnlineLogService = userOnlineLogService; } private ApiResult SendNotice() @@ -130,8 +133,21 @@ public override Task OnDisconnectedAsync(Exception exception) if (userInfo != null) { userInfo.TodayOnlineTime += user?.OnlineTime ?? 0; + + UserOnlineLogService.AddUserOnlineLog(new Model.UserOnlineLog() + { + UserId = user.Userid, + AddTime = DateTime.Now, + Location = user?.Location, + OnlineTime = user.OnlineTime, + UserIP = user.UserIP, + TodayOnlineTime = userInfo.TodayOnlineTime, + Platform = user.Platform, + Remark = user.Browser, + LoginTime = user.LoginTime, + }); } - Log.WriteLine(ConsoleColor.Red, msg: $"用户{user?.Name}离开了,已在线{userInfo?.TodayOnlineTime}分,当前已连接{onlineClients.Count}个"); + Log.WriteLine(ConsoleColor.Red, msg: $"用户{user?.Name}离开了,已在线{userInfo?.TodayOnlineTime}分种,当前已连接{onlineClients.Count}个"); } return base.OnDisconnectedAsync(exception); } diff --git a/ZR.ServiceCore/SqlSugar/DataPermi.cs b/ZR.ServiceCore/SqlSugar/DataPermi.cs index 0de5d4b1..272efec8 100644 --- a/ZR.ServiceCore/SqlSugar/DataPermi.cs +++ b/ZR.ServiceCore/SqlSugar/DataPermi.cs @@ -1,6 +1,7 @@ using Infrastructure; using SqlSugar.IOC; using ZR.Model.System; +using ZR.ServiceCore.Model; namespace ZR.ServiceCore.SqlSugar { @@ -48,6 +49,7 @@ public static void FilterData(int configId) var expUser = Expressionable.Create(); var expRole = Expressionable.Create(); var expLoginlog = Expressionable.Create(); + expUser.And(it => it.DelFlag == 0); foreach (var role in user.Roles.OrderBy(f => f.DataScope)) { @@ -84,6 +86,7 @@ public static void FilterData(int configId) db.QueryFilter.AddTableFilter(expUser.ToExpression()); db.QueryFilter.AddTableFilter(expRole.ToExpression()); db.QueryFilter.AddTableFilter(expLoginlog.ToExpression()); + db.QueryFilter.AddTableFilter(f => f.UserId == user.UserId, QueryFilterProvider.FilterJoinPosition.Where); } } } diff --git a/ZR.ServiceCore/SqlSugar/InitTable.cs b/ZR.ServiceCore/SqlSugar/InitTable.cs index 47c07bff..3ffa3598 100644 --- a/ZR.ServiceCore/SqlSugar/InitTable.cs +++ b/ZR.ServiceCore/SqlSugar/InitTable.cs @@ -52,6 +52,16 @@ public static void InitDb() db.CodeFirst.InitTables(typeof(EmailTpl)); db.CodeFirst.InitTables(typeof(SmsCodeLog)); db.CodeFirst.InitTables(typeof(EmailLog)); + //db.CodeFirst.InitTables(typeof(UserOnlineLog)); + } + public static void InitNewTb() + { + var db = DbScoped.SugarScope; + var t1 = db.DbMaintenance.IsAnyTable(typeof(UserOnlineLog).Name); + if (!t1) + { + db.CodeFirst.InitTables(typeof(UserOnlineLog)); + } } } } diff --git a/ZR.ServiceCore/SqlSugar/SqlsugarSetup.cs b/ZR.ServiceCore/SqlSugar/SqlsugarSetup.cs index 1f08e624..53abaff1 100644 --- a/ZR.ServiceCore/SqlSugar/SqlsugarSetup.cs +++ b/ZR.ServiceCore/SqlSugar/SqlsugarSetup.cs @@ -52,9 +52,13 @@ public static void AddDb(this IServiceCollection services, IWebHostEnvironment e }); }); - if (options.InitDb && environment.IsDevelopment()) + if (environment.IsDevelopment()) { - InitTable.InitDb(); + if (options.InitDb) + { + InitTable.InitDb(); + } + InitTable.InitNewTb(); } } @@ -215,7 +219,7 @@ private static void SetSugarAop(SqlSugarClient db, IocConfig iocConfig, ICacheSe //方法名 var FirstMethodName = db.Ado.SqlStackTrace.FirstMethodName; var logInfo = $"Sql执行超时,用时{db.Ado.SqlExecutionTime.TotalSeconds}秒【{sql}】,fileName={fileName},line={fileLine},methodName={FirstMethodName}"; - WxNoticeHelper.SendMsg("Sql请求时间过长",logInfo); + WxNoticeHelper.SendMsg("Sql请求时间过长", logInfo); logger.Warn(logInfo); } }; diff --git a/ZR.Vue/src/views/article/manager.vue b/ZR.Vue/src/views/article/manager.vue index 118a5687..17822d4a 100644 --- a/ZR.Vue/src/views/article/manager.vue +++ b/ZR.Vue/src/views/article/manager.vue @@ -5,19 +5,19 @@ - + - + - 搜索 - 重置 + 搜索 + 重置 diff --git a/ZR.Vue/src/views/dataScreen/index.vue b/ZR.Vue/src/views/dataScreen/index.vue new file mode 100644 index 00000000..64db54d3 --- /dev/null +++ b/ZR.Vue/src/views/dataScreen/index.vue @@ -0,0 +1,4 @@ + + diff --git a/ZR.Vue/src/views/index.vue b/ZR.Vue/src/views/index.vue index 4dbe4650..0f1a30dd 100644 --- a/ZR.Vue/src/views/index.vue +++ b/ZR.Vue/src/views/index.vue @@ -1,6 +1,5 @@ diff --git a/ZR.Vue/src/views/system/menu/index.vue b/ZR.Vue/src/views/system/menu/index.vue index b96c017b..0a9d2e86 100644 --- a/ZR.Vue/src/views/system/menu/index.vue +++ b/ZR.Vue/src/views/system/menu/index.vue @@ -2,25 +2,25 @@
- + - + - 搜索 - 重置 + 搜索 + 重置 - 新增 + 新增 - 展开/折叠 + 展开/折叠 diff --git a/ZR.Vue/src/views/system/notice/index.vue b/ZR.Vue/src/views/system/notice/index.vue index 301947cc..d18e1c79 100644 --- a/ZR.Vue/src/views/system/notice/index.vue +++ b/ZR.Vue/src/views/system/notice/index.vue @@ -2,48 +2,33 @@
- + - + - + - 搜索 - 重置 + 搜索 + 重置 - 新增 + 新增 - + 修改 - 删除 diff --git a/ZR.Vue/src/views/system/post/index.vue b/ZR.Vue/src/views/system/post/index.vue index 0d0138b1..b48a3f08 100644 --- a/ZR.Vue/src/views/system/post/index.vue +++ b/ZR.Vue/src/views/system/post/index.vue @@ -2,47 +2,38 @@
- + - + - + - 搜索 - 重置 + 搜索 + 重置 - 新增 + 新增 - 修改 - 删除 + + 删除 + - 导出 + 导出 diff --git a/ZR.Vue/src/views/system/role/index.vue b/ZR.Vue/src/views/system/role/index.vue index edd8a44c..a33bc9eb 100644 --- a/ZR.Vue/src/views/system/role/index.vue +++ b/ZR.Vue/src/views/system/role/index.vue @@ -6,7 +6,6 @@ v-model="queryParams.roleName" placeholder="请输入角色名称" clearable - size="small" style="width: 240px" @keyup.enter.native="handleQuery" /> @@ -15,20 +14,20 @@ --> - + - 搜索 - 重置 + 搜索 + 重置 - 新增 + 新增 diff --git a/ZR.Vue/src/views/system/roleusers/index.vue b/ZR.Vue/src/views/system/roleusers/index.vue index c396a5a5..ccd323ab 100644 --- a/ZR.Vue/src/views/system/roleusers/index.vue +++ b/ZR.Vue/src/views/system/roleusers/index.vue @@ -20,22 +20,22 @@ @keyup.enter.native="searchRoleUser" /> - 搜索 + 搜索 - 添加用户 + 添加用户 - + 批量取消授权 - 关闭 + 关闭 diff --git a/ZR.Vue/src/views/system/user/index.vue b/ZR.Vue/src/views/system/user/index.vue index 6bda765c..554b423a 100644 --- a/ZR.Vue/src/views/system/user/index.vue +++ b/ZR.Vue/src/views/system/user/index.vue @@ -8,7 +8,6 @@ v-model="deptName" placeholder="请输入部门名称" clearable - size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" /> @@ -33,7 +32,6 @@ v-model="queryParams.userName" placeholder="请输入用户名称" clearable - size="small" style="width: 240px" @keyup.enter.native="handleQuery" /> @@ -43,7 +41,6 @@ v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable - size="small" style="width: 240px" @keyup.enter.native="handleQuery" /> @@ -57,7 +54,6 @@ - 搜索 - 重置 + 搜索 + 重置 - 新增 + 新增 - 导入 - 导出 diff --git a/ZR.Vue/src/views/tool/gen/editTable.vue b/ZR.Vue/src/views/tool/gen/editTable.vue index fdb11917..d81542ce 100644 --- a/ZR.Vue/src/views/tool/gen/editTable.vue +++ b/ZR.Vue/src/views/tool/gen/editTable.vue @@ -9,9 +9,9 @@ - - - + + +