diff --git a/Api/Ewide.Application/Service/HouseSafety/HouseInfo/HouseInfoService.cs b/Api/Ewide.Application/Service/HouseSafety/HouseInfo/HouseInfoService.cs index 3813291..a162309 100644 --- a/Api/Ewide.Application/Service/HouseSafety/HouseInfo/HouseInfoService.cs +++ b/Api/Ewide.Application/Service/HouseSafety/HouseInfo/HouseInfoService.cs @@ -120,7 +120,7 @@ WHERE HC.Id=@HouseCodeId", new { houseTask.HouseCodeId } var houseEntity = await _houseInfoRep.DetachedEntities.FirstOrDefaultAsync(h => h.HouseCodeId == input.houseCode.Id); //建档审核通过的房屋数据修改时,对应的建档任务Task不处理 - if (houseEntity.State != 6) + if (houseEntity == null || houseEntity.State != 6) { var houseTask = input.PatrolInfo.Adapt(); houseTask.HouseCodeId = input.houseCode.Id; diff --git a/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs b/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs index c0fff75..4aa2e96 100644 --- a/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs +++ b/Api/Ewide.Application/Service/HouseSafety/HouseMember/HouseMemberService.cs @@ -13,6 +13,7 @@ using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System; namespace Ewide.Application.Service { @@ -108,10 +109,10 @@ WHERE 1=1"; var users = await _dapperRepository.QueryPageData(sql, input, param); - foreach (var user in users.Items) - { - user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id); - } + //foreach (var user in users.Items) + //{ + // user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id); + //} return PageDataResult.PageResult(users); } @@ -170,7 +171,10 @@ WHERE 1=1"; [UnitOfWork] public async Task DeleteUser(DeleteUserInput input) { - // 片区监管员在本片区已有安全员的情况下无法删除 + /* + * 未处理逻辑 + * 片区监管员在本片区已有安全员的情况下无法删除 + */ await _sysUserService.DeleteUser(input); } @@ -185,6 +189,7 @@ WHERE 1=1"; public async Task UpdateUser(UpdateUserInput input) { /* + * 未处理逻辑 * 如果移动组织架构,会产生以下几种逻辑 * 片区1监管员(无安全员或有其他监管员)=>片区2,直接成功 * 片区1监管员(有安全员并且无其他监管员)=>片区2,无法移动 @@ -203,7 +208,30 @@ WHERE 1=1"; [HttpGet("/houseMember/detail")] public async Task GetUser([FromQuery] QueryUserInput input) { - return await _sysUserService.GetUser(input); + var sql = @"SELECT +SU.*, +SO.Name OrgName, +SUR.RoleName, +SUR.RoleCode +FROM sys_user SU +LEFT JOIN sys_emp SE ON SU.Id = SE.Id +LEFT JOIN sys_org SO ON SE.OrgId = SO.Id +LEFT JOIN ( + SELECT + SUR.SysUserId, + GROUP_CONCAT(SR.Name) RoleName, + GROUP_CONCAT(SR.Code) RoleCode + FROM sys_user_role SUR + LEFT JOIN sys_role SR ON SUR.SysRoleId = SR.Id + GROUP BY SUR.SysUserId +) SUR ON SU.Id = SUR.SysUserId +WHERE SU.Id=@Id"; + var user = (await _dapperRepository.QueryAsync(sql, new { input.Id })).SingleOrDefault(); + if (user != null) + { + user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id); + } + return user; } /// @@ -254,7 +282,7 @@ WHERE 1=1"; var _sysOrgRep = Db.GetRepository(); var org = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == orgId); // 如果当前组织为街道, 则直接返回安全员 - if (org == null || org.Type <= 30) + if (org == null || org.Type <= (int)OrgType.乡镇街道办事处) { return roles.LastOrDefault(); } @@ -265,7 +293,7 @@ WHERE 1=1"; var roleIds = await _sysUserRoleRep.DetachedEntities.Where(p => userIds.Contains(p.SysUserId)).Select(p => p.SysRoleId).ToListAsync(); var _sysRoleRep = Db.GetRepository(); - var isExistZoneManager = await _sysRoleRep.DetachedEntities.AnyAsync(p => roleIds.Contains(p.Id) && p.Code == System.Enum.GetName(HouseManagerRole.ZoneManager).ToUnderScoreCase()); + var isExistZoneManager = await _sysRoleRep.DetachedEntities.AnyAsync(p => roleIds.Contains(p.Id) && p.Code == Enum.GetName(HouseManagerRole.ZoneManager).ToUnderScoreCase()); // 存在片区监管员,返回安全员, 否则返回监管员 if (isExistZoneManager) { @@ -282,7 +310,10 @@ WHERE 1=1"; [NonAction] private async Task> GetRoleRange() { - var codes = System.Enum.GetNames(typeof(HouseManagerRole)).Select(p => p.ToUnderScoreCase()); + var codes = (new[] { + Enum.GetName(HouseManagerRole.ZoneManager), + Enum.GetName(HouseManagerRole.HouseSecurityManager), + }).Select(p => p.ToUnderScoreCase()); var _sysRoleRep = Db.GetRepository(); var roles = await _sysRoleRep.DetachedEntities.Where(p => codes.Contains(p.Code)).ToListAsync(); diff --git a/Api/Ewide.Core/Enum/MenuType.cs b/Api/Ewide.Core/Enum/MenuType.cs index 80363cd..ddc74ac 100644 --- a/Api/Ewide.Core/Enum/MenuType.cs +++ b/Api/Ewide.Core/Enum/MenuType.cs @@ -20,9 +20,9 @@ namespace Ewide.Core MENU = 1, /// - /// 按钮 + /// 功能 /// - [Description("按钮")] - BTN = 2 + [Description("功能")] + FUNCTION = 2 } } diff --git a/Api/Ewide.Core/Ewide.Core.xml b/Api/Ewide.Core/Ewide.Core.xml index 51a582c..7e5c095 100644 --- a/Api/Ewide.Core/Ewide.Core.xml +++ b/Api/Ewide.Core/Ewide.Core.xml @@ -2417,9 +2417,9 @@ 菜单 - + - 按钮 + 功能 @@ -4933,7 +4933,7 @@ 路由元信息(路由附带扩展信息) - + 路径 @@ -4943,6 +4943,11 @@ 控制路由和子路由是否显示在 sidebar + + + 打开方式 + + 路由元信息内部类 @@ -5068,6 +5073,11 @@ 菜单类型(字典 0目录 1菜单 2按钮) + + + 打开方式(字典 0无 1组件 2内链 3外链) + + 菜单Id diff --git a/Api/Ewide.Core/Filter/RequestActionFilter.cs b/Api/Ewide.Core/Filter/RequestActionFilter.cs index fa6ce44..6a37036 100644 --- a/Api/Ewide.Core/Filter/RequestActionFilter.cs +++ b/Api/Ewide.Core/Filter/RequestActionFilter.cs @@ -8,6 +8,8 @@ using System.Diagnostics; using System.Security.Claims; using System.Threading.Tasks; using UAParser; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Ewide.Core { @@ -34,12 +36,29 @@ namespace Ewide.Core var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; var descAtt = Attribute.GetCustomAttribute(actionDescriptor.MethodInfo, typeof(DescriptionAttribute)) as DescriptionAttribute; + var message = "请求成功"; + if (isRequestSucceed) + { + var result = actionContext.Result; + var resultType = result.GetType(); + if (resultType.Name == "ContentResult") + { + var resultContent = ((Microsoft.AspNetCore.Mvc.ContentResult)actionContext.Result)?.Content; + var resultJson = JsonConvert.DeserializeObject(resultContent); + message = resultJson["message"]?.ToString(); + } + } + else + { + message = actionContext.Exception.Message; + } + var sysOpLog = new SysLogOp { Name = descAtt != null ? descAtt.Description : actionDescriptor.ActionName, OpType = 1, Success = isRequestSucceed, - //Message = isRequestSucceed ? "成功" : "失败", + Message = message, Ip = httpContext.GetRemoteIpAddressToIPv4(), Location = httpRequest.GetRequestUrlAddress(), Browser = clent.UA.Family + clent.UA.Major, @@ -48,13 +67,13 @@ namespace Ewide.Core ClassName = context.Controller.ToString(), MethodName = actionDescriptor.ActionName, ReqMethod = httpRequest.Method, - //Param = JsonSerializerUtility.Serialize(context.ActionArguments), - //Result = JsonSerializerUtility.Serialize(actionContext.Result), + Param = JsonConvert.SerializeObject(context.ActionArguments), + // Result = resultContent, ElapsedTime = sw.ElapsedMilliseconds, OpTime = DateTime.Now, Account = httpContext.User?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT) }; - await sysOpLog.InsertAsync(); + await sysOpLog.InsertNowAsync(); } } } diff --git a/Api/Ewide.Core/Service/Auth/AuthService.cs b/Api/Ewide.Core/Service/Auth/AuthService.cs index b9b3773..fba2662 100644 --- a/Api/Ewide.Core/Service/Auth/AuthService.cs +++ b/Api/Ewide.Core/Service/Auth/AuthService.cs @@ -101,6 +101,24 @@ namespace Ewide.Core.Service // 设置刷新Token令牌 _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken; + // 增加登录日志 + var loginOutput = user.Adapt(); + var clent = Parser.GetDefault().Parse(App.GetService().HttpContext.Request.Headers["User-Agent"]); + loginOutput.LastLoginBrowser = clent.UA.Family + clent.UA.Major; + loginOutput.LastLoginOs = clent.OS.Family + clent.OS.Major; + await new SysLogVis + { + Name = "登录", + Success = true, + Message = "登录成功", + Ip = loginOutput.LastLoginIp, + Browser = loginOutput.LastLoginBrowser, + Os = loginOutput.LastLoginOs, + VisType = 1, + VisTime = loginOutput.LastLoginTime, + Account = loginOutput.Account + }.InsertAsync(); + return accessToken; } @@ -163,20 +181,6 @@ namespace Ewide.Core.Service loginOutput.Menus = await _sysMenuService.GetLoginMenusAntDesign(userId, defaultActiveAppCode); } - // 增加登录日志 - //await new SysLogVis - //{ - // Name = "登录", - // Success = true, - // Message = "登录成功", - // Ip = loginOutput.LastLoginIp, - // Browser = loginOutput.LastLoginBrowser, - // Os = loginOutput.LastLoginOs, - // VisType = 1, - // VisTime = loginOutput.LastLoginTime, - // Account = loginOutput.Account - //}.InsertAsync(); - return loginOutput; } diff --git a/Api/Ewide.Core/Service/Log/SysOpLogService.cs b/Api/Ewide.Core/Service/Log/SysOpLogService.cs index 7c23226..5a6e346 100644 --- a/Api/Ewide.Core/Service/Log/SysOpLogService.cs +++ b/Api/Ewide.Core/Service/Log/SysOpLogService.cs @@ -1,4 +1,5 @@ -using Ewide.Core.Extension; +using Dapper; +using Ewide.Core.Extension; using Furion.DatabaseAccessor; using Furion.DatabaseAccessor.Extensions; using Furion.DependencyInjection; @@ -20,10 +21,12 @@ namespace Ewide.Core.Service public class SysOpLogService : ISysOpLogService, IDynamicApiController, ITransient { private readonly IRepository _sysOpLogRep; // 操作日志表仓储 + private readonly IDapperRepository _dapperRepository; - public SysOpLogService(IRepository sysOpLogRep) + public SysOpLogService(IRepository sysOpLogRep, IDapperRepository dapperRepository) { _sysOpLogRep = sysOpLogRep; + _dapperRepository = dapperRepository; } /// @@ -54,11 +57,7 @@ namespace Ewide.Core.Service [HttpPost("/sysOpLog/delete")] public async Task ClearOpLog() { - var opLogs = await _sysOpLogRep.Entities.ToListAsync(); - opLogs.ForEach(u => - { - u.Delete(); - }); + await _dapperRepository.ExecuteAsync("DELETE FROM sys_log_op"); } } } diff --git a/Api/Ewide.Core/Service/Menu/Dto/AntDesignTreeNode.cs b/Api/Ewide.Core/Service/Menu/Dto/AntDesignTreeNode.cs index adec4a9..8739f9e 100644 --- a/Api/Ewide.Core/Service/Menu/Dto/AntDesignTreeNode.cs +++ b/Api/Ewide.Core/Service/Menu/Dto/AntDesignTreeNode.cs @@ -38,12 +38,17 @@ /// /// 路径 /// - public string Path { get; set; } + public string Link { get; set; } /// /// 控制路由和子路由是否显示在 sidebar /// public bool Hidden { get; set; } + + /// + /// 打开方式 + /// + public int OpenType { get; set; } } /// diff --git a/Api/Ewide.Core/Service/Menu/Dto/MenuInput.cs b/Api/Ewide.Core/Service/Menu/Dto/MenuInput.cs index 4c86f61..eae1c9d 100644 --- a/Api/Ewide.Core/Service/Menu/Dto/MenuInput.cs +++ b/Api/Ewide.Core/Service/Menu/Dto/MenuInput.cs @@ -25,7 +25,7 @@ namespace Ewide.Core.Service /// /// 菜单类型(字典 0目录 1菜单 2按钮) /// - public virtual string Type { get; set; } + public virtual int Type { get; set; } /// /// 图标 @@ -55,7 +55,7 @@ namespace Ewide.Core.Service /// /// 打开方式(字典 0无 1组件 2内链 3外链) /// - public virtual string OpenType { get; set; } + public virtual int OpenType { get; set; } /// /// 是否可见(Y-是,N-否) @@ -99,7 +99,13 @@ namespace Ewide.Core.Service /// 菜单类型(字典 0目录 1菜单 2按钮) /// [Required(ErrorMessage = "菜单类型不能为空")] - public override string Type { get; set; } + public override int Type { get; set; } + + /// + /// 打开方式(字典 0无 1组件 2内链 3外链) + /// + [Required(ErrorMessage = "打开方式不能为空")] + public override int OpenType { get; set; } } public class DeleteMenuInput diff --git a/Api/Ewide.Core/Service/Menu/SysMenuService.cs b/Api/Ewide.Core/Service/Menu/SysMenuService.cs index fa73ffa..b9d3572 100644 --- a/Api/Ewide.Core/Service/Menu/SysMenuService.cs +++ b/Api/Ewide.Core/Service/Menu/SysMenuService.cs @@ -53,7 +53,7 @@ namespace Ewide.Core.Service var roleIdList = await _sysUserRoleService.GetUserRoleIdList(userId); var menuIdList = await _sysRoleMenuService.GetRoleMenuIdList(roleIdList); permissions = await _sysMenuRep.DetachedEntities.Where(u => menuIdList.Contains(u.Id)) - .Where(u => u.Type == (int)MenuType.BTN) + .Where(u => u.Type == (int)MenuType.FUNCTION) .Where(u => u.Status == (int)CommonStatus.ENABLE) .Select(u => u.Permission).ToListAsync(); #if DEBUG @@ -83,8 +83,8 @@ namespace Ewide.Core.Service sysMenuList = await _sysMenuRep.DetachedEntities .Where(u => u.Status == (int)CommonStatus.ENABLE) .Where(u => u.Application == appCode) - .Where(u => u.Type != (int)MenuType.BTN) - //.Where(u => u.Weight != (int)MenuWeight.DEFAULT_WEIGHT) + .Where(u => u.Type != (int)MenuType.FUNCTION) + .Where(u => u.Weight != (int)MenuWeight.DEFAULT_WEIGHT) .OrderBy(u => u.Sort).ToListAsync(); } else @@ -96,7 +96,7 @@ namespace Ewide.Core.Service .Where(u => menuIdList.Contains(u.Id)) .Where(u => u.Status == (int)CommonStatus.ENABLE) .Where(u => u.Application == appCode) - .Where(u => u.Type != (int)MenuType.BTN) + .Where(u => u.Type != (int)MenuType.FUNCTION) .OrderBy(u => u.Sort).ToListAsync(); } // 转换成登录菜单 @@ -106,8 +106,9 @@ namespace Ewide.Core.Service Pid = u.Pid, Name = u.Code, Component = u.Component, - Redirect = u.OpenType == (int)MenuOpenType.OUTER ? u.Link : u.Redirect, - Path = u.OpenType == (int)MenuOpenType.OUTER ? u.Link : u.Router, + Redirect = u.Redirect, + Link = u.Link, + OpenType = u.OpenType, Meta = new Meta { Title = u.Name, @@ -185,7 +186,7 @@ namespace Ewide.Core.Service /// 增加和编辑时检查参数 /// /// - private static void CheckMenuParam(MenuInput input) + private async Task CheckMenuParam(MenuInput input) { var type = input.Type; var router = input.Router; @@ -195,17 +196,17 @@ namespace Ewide.Core.Service if (type.Equals((int)MenuType.DIR)) { - if (string.IsNullOrEmpty(router)) - throw Oops.Oh(ErrorCode.D4001); + //if (string.IsNullOrEmpty(router)) + // throw Oops.Oh(ErrorCode.D4001); } else if (type.Equals((int)MenuType.MENU)) { - if (string.IsNullOrEmpty(router)) - throw Oops.Oh(ErrorCode.D4001); - if (string.IsNullOrEmpty(openType)) - throw Oops.Oh(ErrorCode.D4002); + //if (string.IsNullOrEmpty(router)) + // throw Oops.Oh(ErrorCode.D4001); + //if (string.IsNullOrEmpty(openType)) + // throw Oops.Oh(ErrorCode.D4002); } - else if (type.Equals((int)MenuType.BTN)) + else if (type.Equals((int)MenuType.FUNCTION)) { if (string.IsNullOrEmpty(permission)) throw Oops.Oh(ErrorCode.D4003); @@ -217,10 +218,37 @@ namespace Ewide.Core.Service //if (!urlSet.Contains(permission.Replace(":","/"))) // throw Oops.Oh(ErrorCode.meu1005); } - //按钮可以设置绑定菜单 - if(!isVisibleParent && type.Equals((int)MenuType.BTN)) + + // 检查上级菜单的类型是否正确 + var pid = input.Pid; + var flag = true; + var empty = System.Guid.Empty.ToString(); + switch(type) { - throw Oops.Oh(ErrorCode.D4004); + // 目录必须在顶级下 + case (int)MenuType.DIR: + flag = pid.Equals(empty); + break; + // 菜单必须在顶级或目录下 + case (int)MenuType.MENU: + if (!pid.Equals(empty)) + { + var parent = await _sysMenuRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == pid); + flag = parent.Type.Equals((int)MenuType.DIR); + } + break; + // 功能必须在菜单下 + case (int)MenuType.FUNCTION: + { + var parent = await _sysMenuRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == pid); + flag = parent == null ? false : parent.Type.Equals((int)MenuType.MENU); + } + break; + } + + if (!flag) + { + throw Oops.Oh("父级菜单类型错误"); } } @@ -240,7 +268,7 @@ namespace Ewide.Core.Service } // 校验参数 - CheckMenuParam(input); + await CheckMenuParam(input); var menu = input.Adapt(); menu.Pids = await CreateNewPids(input.Pid); @@ -296,7 +324,7 @@ namespace Ewide.Core.Service } // 校验参数 - CheckMenuParam(input); + await CheckMenuParam(input); // 如果是编辑,父id不能为自己的子节点 var childIdList = await _sysMenuRep.DetachedEntities.Where(u => u.Pids.Contains(input.Id.ToString())) .Select(u => u.Id).ToListAsync(); @@ -360,7 +388,7 @@ namespace Ewide.Core.Service // 更新当前菜单 oldMenu = input.Adapt(); oldMenu.Pids = newPids; - await oldMenu.UpdateAsync(ignoreNullValues: true); + await oldMenu.UpdateExcludeAsync(new[] { nameof(SysMenu.Type) }, ignoreNullValues: true); // 清除缓存 await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_MENU); diff --git a/Api/Ewide.Core/Service/User/SysUserService.cs b/Api/Ewide.Core/Service/User/SysUserService.cs index d6646a8..53e18a4 100644 --- a/Api/Ewide.Core/Service/User/SysUserService.cs +++ b/Api/Ewide.Core/Service/User/SysUserService.cs @@ -92,10 +92,10 @@ namespace Ewide.Core.Service // emps.Add(_sysEmpService.GetEmpInfo(long.Parse(u.Id))); //}); //await Task.WhenAll(emps); - foreach (var user in users.Items) - { - user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id); - } + //foreach (var user in users.Items) + //{ + // user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id); + //} return PageDataResult.PageResult(users); } @@ -176,8 +176,17 @@ namespace Ewide.Core.Service if (isExist) throw Oops.Oh(ErrorCode.D1003); var user = input.Adapt(); - await user.UpdateExcludeAsync(new[] { nameof(SysUser.Password), nameof(SysUser.Status), nameof(SysUser.AdminType) }, true); - user.UpdateIncludeNow(new[] { nameof(SysUser.Birthday) }); + await user.UpdateIncludeAsync(new[] { + nameof(SysUser.Account), + nameof(SysUser.NickName), + nameof(SysUser.Name), + nameof(SysUser.Birthday), + nameof(SysUser.Sex), + nameof(SysUser.Email), + nameof(SysUser.Phone), + nameof(SysUser.Tel), + }, true); + // user.UpdateIncludeNow(new[] { nameof(SysUser.Birthday) }); input.SysEmpParam.Id = user.Id.ToString(); // 更新员工及附属机构职位信息 await _sysEmpService.AddOrUpdate(input.SysEmpParam); diff --git a/web-react/package.json b/web-react/package.json index 502591d..8de0070 100644 --- a/web-react/package.json +++ b/web-react/package.json @@ -20,6 +20,7 @@ "photoswipe": "^4.1.3", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-json-view": "^1.21.3", "react-monaco-editor": "^0.43.0", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", @@ -58,4 +59,4 @@ "last 1 safari version" ] } -} \ No newline at end of file +} diff --git a/web-react/public/seed/query-table-form/form.jsx b/web-react/public/seed/query-table-form/form.jsx index 0c83022..cebd795 100644 --- a/web-react/public/seed/query-table-form/form.jsx +++ b/web-react/public/seed/query-table-form/form.jsx @@ -1,7 +1,7 @@ import React, { Component } from 'react' import { Form, Spin } from 'antd' import { AntIcon } from 'components' -import { cloneDeep } from 'lodash' +import { api } from 'common/api' const initialValues = {} @@ -31,14 +31,15 @@ export default class form extends Component { * @param {*} params */ async fillData(params) { - this.record = cloneDeep(params.record) + const state = { loading: false } //#region 从后端转换成前段所需格式,也可以在此处调用获取详细数据接口 + if (params.id) { + this.record = (await api).data + } //#endregion this.form.current.setFieldsValue(this.record) - this.setState({ - loading: false, - }) + this.setState(state) } /** diff --git a/web-react/public/seed/query-table/index.jsx b/web-react/public/seed/query-table/index.jsx index def3cf2..95eb779 100644 --- a/web-react/public/seed/query-table/index.jsx +++ b/web-react/public/seed/query-table/index.jsx @@ -63,16 +63,16 @@ export default class index extends Component { title: '操作', width: 150, dataIndex: 'actions', - render: (text, record) => ( + render: (text, { id }) => ( - this.onOpen(this.editForm, record)}>编辑 + this.onOpen(this.editForm, id)}>编辑 this.onDelete(record)} + onConfirm={() => this.onDelete(id)} > 删除 @@ -145,12 +145,10 @@ export default class index extends Component { /** * 打开新增/编辑弹窗 * @param {*} modal - * @param {*} record + * @param {*} id */ - onOpen(modal, record) { - modal.current.open({ - record, - }) + onOpen(modal, id) { + modal.current.open({ id }) } /** @@ -177,10 +175,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} id */ - onDelete(record) { - this.onAction(apiAction.delete(record), '删除成功') + onDelete(id) { + this.onAction(apiAction.delete({ id }), '删除成功') } //#region 自定义方法 diff --git a/web-react/src/assets/style/lib/list.less b/web-react/src/assets/style/lib/list.less index f8a937f..2dbb2de 100644 --- a/web-react/src/assets/style/lib/list.less +++ b/web-react/src/assets/style/lib/list.less @@ -26,7 +26,7 @@ } } } - >.ant-pagination { + .ant-pagination { margin: @padding-md 0; } .ant-descriptions { @@ -44,6 +44,14 @@ } } } + &--scroll { + position: relative; + + overflow-x: auto; + } + .ant-list-items { + min-width: 1000px; + } .ant-list-item { transition: @animation-duration-slow; transition-property: background, border-bottom-color; @@ -52,4 +60,36 @@ background: linear-gradient(90deg, transparent 10%, @background-color-light 70%, transparent); } } + &-container { + position: relative; + &::before, + &::after { + position: absolute; + top: 0; + bottom: 0; + z-index: 3; + + width: 30px; + + content: ''; + transition: box-shadow @animation-duration-slow; + pointer-events: none; + } + &::before { + left: 0; + } + &::after { + right: 0; + } + &.yo-list--ping-left { + &::before { + box-shadow: inset 10px 0 8px -8px fade(@black, 15%); + } + } + &.yo-list--ping-right { + &::after { + box-shadow: inset -10px 0 8px -8px fade(@black, 15%); + } + } + } } diff --git a/web-react/src/assets/style/lib/table.less b/web-react/src/assets/style/lib/table.less index 9bde634..6ed273f 100644 --- a/web-react/src/assets/style/lib/table.less +++ b/web-react/src/assets/style/lib/table.less @@ -22,6 +22,14 @@ } } } +.ant-table { + .ant-table-container { + &::before, + &::after { + z-index: 3; + } + } +} .ant-table-thead { th.ant-table-column-has-sorters { &:hover { diff --git a/web-react/src/assets/style/lib/tree-layout.less b/web-react/src/assets/style/lib/tree-layout.less index 4b1cc97..a54090a 100644 --- a/web-react/src/assets/style/lib/tree-layout.less +++ b/web-react/src/assets/style/lib/tree-layout.less @@ -19,6 +19,20 @@ } } } + &--collapsed { + position: absolute; + top: 0; + left: 0; + bottom: 0; + z-index: 4; + + transform: translateX(-100%); + &.open { + transform: translateX(0); + + box-shadow: 2px 0 8px fade(@black , 20%); + } + } &--bar { line-height: 20px; diff --git a/web-react/src/assets/style/lib/visibility.less b/web-react/src/assets/style/lib/visibility.less index a782155..3e16f62 100644 --- a/web-react/src/assets/style/lib/visibility.less +++ b/web-react/src/assets/style/lib/visibility.less @@ -26,3 +26,21 @@ white-space: nowrap; text-overflow: ellipsis; } +.ellipsis-2 { + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; + + text-overflow: ellipsis; + + -webkit-line-clamp: 2; +} +.ellipsis-3 { + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; + + text-overflow: ellipsis; + + -webkit-line-clamp: 3; +} diff --git a/web-react/src/assets/style/main.less b/web-react/src/assets/style/main.less index 7cf67c9..3abb0d5 100644 --- a/web-react/src/assets/style/main.less +++ b/web-react/src/assets/style/main.less @@ -300,6 +300,14 @@ opacity: 0; } + >iframe { + display: block; + + width: 100%; + height: 100%; + + border: 0; + } } } } diff --git a/web-react/src/common/api/requests/business/houseSafety/houseInfo.js b/web-react/src/common/api/requests/business/houseSafety/houseInfo.js index 7d6a58e..0177ae8 100644 --- a/web-react/src/common/api/requests/business/houseSafety/houseInfo.js +++ b/web-react/src/common/api/requests/business/houseSafety/houseInfo.js @@ -1,6 +1,7 @@ const urls = { houseInfoGetByTaskId: ['/houseInfo/getByTaskId', 'get'], - houseInfoSave: ['houseInfo/save', 'post'] + houseInfoSave: ['houseInfo/save', 'post'], + houseInfoSubmitToCheck: ['/houseInfo/submitToCheck', 'post'] } export default urls \ No newline at end of file diff --git a/web-react/src/common/api/requests/business/houseSafety/houseMember.js b/web-react/src/common/api/requests/business/houseSafety/houseMember.js index bf8c24f..74654c3 100644 --- a/web-react/src/common/api/requests/business/houseSafety/houseMember.js +++ b/web-react/src/common/api/requests/business/houseSafety/houseMember.js @@ -3,6 +3,7 @@ const urls = { houseMemberAdd: ['/houseMember/add', 'post'], houseMemberEdit: ['/houseMember/edit', 'post'], houseMemberDelete: ['/houseMember/delete', 'post'], + houseMemberDetail: ['/houseMember/detail', 'detail'], houseMemberOwnRole: ['/houseMember/ownRole', 'get'], houseMemberOwnData: ['/houseMember/ownData', 'get'], houseMemberGrantData: ['/houseMember/grantData', 'post'], diff --git a/web-react/src/common/api/requests/sys/appManage.js b/web-react/src/common/api/requests/sys/appManage.js index 06447d5..0596537 100644 --- a/web-react/src/common/api/requests/sys/appManage.js +++ b/web-react/src/common/api/requests/sys/appManage.js @@ -28,6 +28,7 @@ const urls = { * 修改应用状态 */ sysAppChangeStatus: ['/sysApp/changeStatus', 'post'], + sysAppDetail: ['/sysApp/detail', 'get'] } export default urls \ No newline at end of file diff --git a/web-react/src/components/authority-view/index.jsx b/web-react/src/components/authority-view/index.jsx index adabbe9..e6c220f 100644 --- a/web-react/src/components/authority-view/index.jsx +++ b/web-react/src/components/authority-view/index.jsx @@ -17,11 +17,11 @@ function getVisible() { const caseChildren = checked.filter(item => item.visibleParent || item.type != 2) const visibleParents = [] // 递归寻找父级 - const findVisibleParents = (children) => { + const findVisibleParents = children => { const parents = [] children.forEach(item => { if (item.parentId) { - const parent = this.list.find(item => item.id === item.parentId) + const parent = this.list.find(p => p.id === item.parentId) if (parent) { parents.push(parent) visibleParents.push(parent) @@ -50,7 +50,9 @@ function getVisible() { function renderDescriptions(data) { return data.map(item => { - return item.children && item.children.length ? renderItem.call(this, item) : renderCheckbox.call(this, item) + return item.children && item.children.length + ? renderItem.call(this, item) + : renderCheckbox.call(this, item) }) } @@ -63,8 +65,10 @@ function renderItem(data) { value={data.id} checked={data.checked} indeterminate={data.indeterminate} - onChange={(e) => this.onChange(e, data)} - >{data.title} + onChange={e => this.onChange(e, data)} + > + {data.title} + } > {renderDescriptions.call(this, data.children)} @@ -76,26 +80,22 @@ function renderItem(data) { function renderCheckbox(data) { return (
- this.onChange(e, data)} - >{data.title} - { - data.visibleParent && data.type == 2 && + this.onChange(e, data)}> + {data.title} + + {data.visibleParent && data.type == 2 && ( - } + )}
) } export default class AuthorityView extends Component { - state = { loading: false, - dataSource: [] + dataSource: [], } list = [] @@ -104,7 +104,8 @@ export default class AuthorityView extends Component { super(props) this.autoLoad = typeof this.props.autoLoad === 'boolean' ? this.props.autoLoad : true - this.loadData = typeof this.props.loadData === 'function' ? this.props.loadData : async () => { } + this.loadData = + typeof this.props.loadData === 'function' ? this.props.loadData : async () => {} } /** @@ -126,7 +127,10 @@ export default class AuthorityView extends Component { if (this.props.defaultSelectedKeys) { this.list.map(item => { - if (this.props.defaultSelectedKeys.includes(item.id) && (!item.children || !item.children.length)) { + if ( + this.props.defaultSelectedKeys.includes(item.id) && + (!item.children || !item.children.length) + ) { this.onSelect(true, item) } }) @@ -134,8 +138,10 @@ export default class AuthorityView extends Component { this.setState({ dataSource: res, - loading: false + loading: false, }) + + this.onChange() } onReloadData = () => { @@ -143,16 +149,18 @@ export default class AuthorityView extends Component { } onChange = (e, item) => { - this.onSelect(e.target.checked, item) + if (e && item) { + this.onSelect(e.target.checked, item) + } const visible = getVisible.call(this) if (this.props.onSelect) { this.props.onSelect( // 返回所有选中 - this.list.filter(item => item.checked).map(item => item.id), + this.list.filter(p => p.checked).map(p => p.id), // 返回所有选中和半选 - this.list.filter(item => item.checked || item.indeterminate).map(item => item.id), + this.list.filter(p => p.checked || p.indeterminate).map(p => p.id), // 返回所有选中和半选,但是不返回没有子级选中visibleParent的半选 visible ) @@ -170,7 +178,7 @@ export default class AuthorityView extends Component { } this.setState({ - dataSource: this.list.filter(item => item.parentId === EMPTY_ID) + dataSource: this.list.filter(p => p.parentId === EMPTY_ID), }) } @@ -210,31 +218,30 @@ export default class AuthorityView extends Component { return (
}> - { - !this.state.loading ? - - { - this.state.dataSource.map(item => { - return ( - this.onChange(e, item)} - >{item.title} - } + {!this.state.loading ? ( + + {this.state.dataSource.map(item => { + return ( + this.onChange(e, item)} > - {renderDescriptions.call(this, item.children)} - - ) - }) - } - - : - - } + {item.title} + + } + > + {renderDescriptions.call(this, item.children)} + + ) + })} + + ) : ( + + )}
) diff --git a/web-react/src/components/modal-form/index.jsx b/web-react/src/components/modal-form/index.jsx index 5b47046..5b86f51 100644 --- a/web-react/src/components/modal-form/index.jsx +++ b/web-react/src/components/modal-form/index.jsx @@ -3,56 +3,62 @@ import { Button, Drawer, message as Message, Modal } from 'antd' import { cloneDeep, isEqual } from 'lodash' /** - * 渲染对话框 - * @param {*} props - * @param {*} on - * @param {*} childWithProps - * @returns - */ + * 渲染对话框 + * @param {*} props + * @param {*} on + * @param {*} childWithProps + * @returns + */ function renderModal(props, on, childWithProps) { - on = { ...on, - onCancel: () => this.onClose() + onCancel: () => this.onClose(), } - return - {childWithProps} - - + return ( + + {childWithProps} + + ) } /** * 渲染抽屉 - * @param {*} props - * @param {*} on - * @param {*} childWithProps - * @returns + * @param {*} props + * @param {*} on + * @param {*} childWithProps + * @returns */ function renderDrawer(props, on, childWithProps) { on = { ...on, - onClose: () => this.onClose() + onClose: () => this.onClose(), } - return -
- {childWithProps} -
-
- - -
-
+ // react在这里会对该组件不存在的props抛出异常 + ;['action', 'onSuccess', 'onOk', 'confirmLoading'].forEach(p => { + delete props[p] + }) + + return ( + on.onClose()}> +
{childWithProps}
+
+ + +
+
+ ) } export default class ModalForm extends Component { - state = { // 弹窗显示/隐藏 visible: false, // 提交状态 - confirmLoading: false + confirmLoading: false, } // 子元素实例 @@ -67,12 +73,11 @@ export default class ModalForm extends Component { snapshot = null // 完成操作 - action = async () => { } + action = async () => {} // 是否在关闭时校验数据改变 compareOnClose = true - constructor(props) { super(props) @@ -93,7 +98,7 @@ export default class ModalForm extends Component { /** * 打开弹窗 - * @param {*} data + * @param {*} data */ open = (data = {}) => { this.data = data @@ -110,7 +115,7 @@ export default class ModalForm extends Component { /** * 子元素创建后回调 * 对子元素数据进行填充,(如需关闭时对比)之后再获取结构调整后的数据快照 - * @returns + * @returns */ onCreated = async () => { const body = this.childNode.current @@ -126,7 +131,7 @@ export default class ModalForm extends Component { /** * 取消编辑 * (如需关闭时对比)获取当前数据结构与快照对比 - * @returns + * @returns */ onClose = async () => { const body = this.childNode.current @@ -143,7 +148,7 @@ export default class ModalForm extends Component { content: '当前内容已更改,是否确认不保存并且关闭', onOk: () => { this.close() - } + }, }) return } @@ -155,7 +160,7 @@ export default class ModalForm extends Component { /** * 完成编辑 * 校验并获取结构调整后的数据,调用this.action进行操作 - * @returns + * @returns */ onOk = async () => { const body = this.childNode.current @@ -175,39 +180,33 @@ export default class ModalForm extends Component { this.props.onSuccess(postData) } } - } finally { this.setState({ confirmLoading: false }) } } render() { - const props = { ...this.props, visible: this.state.visible, destroyOnClose: true, - confirmLoading: this.state.confirmLoading + confirmLoading: this.state.confirmLoading, } const on = { - onOk: () => this.onOk() + onOk: () => this.onOk(), } - const childWithProps = React.cloneElement( - React.Children.only(this.props.children), - { - created: childNode => { - this.childNode.current = childNode - this.onCreated() - } - } - ) + const childWithProps = React.cloneElement(React.Children.only(this.props.children), { + created: childNode => { + this.childNode.current = childNode + this.onCreated() + }, + }) - return this.type === 'modal' ? - renderModal.call(this, props, on, childWithProps) - : - renderDrawer.call(this, props, on, childWithProps) + return this.type === 'modal' + ? renderModal.call(this, props, on, childWithProps) + : renderDrawer.call(this, props, on, childWithProps) } } diff --git a/web-react/src/components/query-list/index.jsx b/web-react/src/components/query-list/index.jsx index e623731..c052306 100644 --- a/web-react/src/components/query-list/index.jsx +++ b/web-react/src/components/query-list/index.jsx @@ -43,6 +43,8 @@ export default class QueryList extends Component { state = { loading: false, dataSource: [], + + ping: [], } // 查询表单实例 @@ -91,6 +93,12 @@ export default class QueryList extends Component { if (this.autoLoad) { this.onLoadData() } + + window.addEventListener('resize', this.onResizeScroll) + } + + componentWillUnmount() { + window.removeEventListener('resize', this.onResizeScroll) } /** @@ -108,9 +116,14 @@ export default class QueryList extends Component { this.query ) - this.setState({ - dataSource: res.rows || res.data || res.items, - }) + this.setState( + { + dataSource: res.rows || res.data || res.items, + }, + () => { + this.onResizeScroll() + } + ) this.pagination.total = res.totalCount @@ -174,7 +187,26 @@ export default class QueryList extends Component { this.onLoadData() } + onResizeScroll = () => { + this.onListScrollX({ target: this.refs['scroll-x'] }) + } + + onListScrollX(e) { + const { offsetWidth, scrollWidth, scrollLeft } = e.target + const ping = [] + if (offsetWidth + scrollLeft < scrollWidth && scrollLeft > 0) { + ping.push(...['left', 'right']) + } else if (offsetWidth + scrollLeft < scrollWidth) { + ping.push('right') + } else if (offsetWidth + scrollLeft >= scrollWidth && offsetWidth < scrollWidth) { + ping.push('left') + } + this.setState({ ping }) + } + render() { + const { loading, dataSource, ping } = this.state + const attrs = {} Object.keys(this.props).forEach(key => { if (!propsMap.includes(key)) { @@ -206,9 +238,21 @@ export default class QueryList extends Component {
- }> - - {!!this.state.dataSource && !!this.state.dataSource.length && ( + }> +
`yo-list--ping-${p}`)] + .filter(p => p) + .join(' ')} + > +
this.onListScrollX(e)} + > + +
+
+ {!!dataSource && !!dataSource.length && ( action) - .forEach((action, i) => { - actions.push(action) - if (i < this.props.children.length - 1) { - actions.push() - } - }) : (actions.push(children)) + Array.isArray(children) + ? children + .filter(action => action) + .forEach((action, i) => { + actions.push(action, ) + }) + : actions.push(children) return actions } export default class QueryTableActions extends Component { + componentDidMount() { + // 删除多余的间隔线 + const className = 'ant-divider ant-divider-vertical' + let series = false + for (const node of this.refs.inner.childNodes) { + if ( + (series && node.className == className) || + (!node.nextElementSibling && node.className == className) + ) { + node.remove() + series = false + } else if (node.className == className) { + series = true + } else { + series = false + } + } + } render() { return (
-
+
{renderActions.call(this)}
diff --git a/web-react/src/components/query-table/index.jsx b/web-react/src/components/query-table/index.jsx index d28e0fe..750906b 100644 --- a/web-react/src/components/query-table/index.jsx +++ b/web-react/src/components/query-table/index.jsx @@ -298,7 +298,7 @@ export default class QueryTable extends Component { columns: (() => { const c = [] if (type !== 'tree' && rowNumber & !expandable & !expandedRowRender) { - c.push(rowNoColumn) + //c.push(rowNoColumn) } c.push(...(columns || [])) return c.filter(p => !p.hidden) diff --git a/web-react/src/components/query-tree-layout/index.jsx b/web-react/src/components/query-tree-layout/index.jsx index d7c4466..fd65fb2 100644 --- a/web-react/src/components/query-tree-layout/index.jsx +++ b/web-react/src/components/query-tree-layout/index.jsx @@ -1,6 +1,7 @@ import React, { Component } from 'react' -import { Breadcrumb, Empty, Input, Layout, Spin, Tooltip, Tree } from 'antd' +import { Breadcrumb, Button, Col, Empty, Input, Layout, Row, Spin, Tooltip, Tree } from 'antd' import { AntIcon, Container } from 'components' +import { SIDER_BREAK_POINT } from 'util/global' function generateKey(data, level) { const n = level || [0] @@ -23,7 +24,7 @@ function generateList(data) { this.list.push({ key, [this.replaceFields.value]: data[i][this.replaceFields.value], - [this.replaceFields.title]: data[i][this.replaceFields.title] + [this.replaceFields.title]: data[i][this.replaceFields.title], }) if (data[i][this.replaceFields.children]) { generateList.call(this, data[i][this.replaceFields.children]) @@ -32,7 +33,7 @@ function generateList(data) { } function getParentKey(key, tree) { - let parentKey; + let parentKey for (let i = 0; i < tree.length; i++) { const node = tree[i] if (node[this.replaceFields.children]) { @@ -43,23 +44,26 @@ function getParentKey(key, tree) { } } } - return parentKey; + return parentKey } function renderTitle(nodeData) { const title = nodeData[this.replaceFields.title] if (this.state.searchValue && title.indexOf(this.state.searchValue) > -1) { - return <> - {title.substr(0, title.indexOf(this.state.searchValue))} - {this.state.searchValue} - {title.substr(title.indexOf(this.state.searchValue) + this.state.searchValue.length)} - + return ( + <> + {title.substr(0, title.indexOf(this.state.searchValue))} + {this.state.searchValue} + {title.substr( + title.indexOf(this.state.searchValue) + this.state.searchValue.length + )} + + ) } return <>{title} } function renderBreadcrumbItem() { - const path = ['顶级'] const findPath = (data, level) => { @@ -91,14 +95,16 @@ function renderBreadcrumbItem() { } export default class QueryTreeLayout extends Component { - state = { loading: false, dataSource: [], expandedKeys: [], selectedKey: '', autoExpandParent: true, - searchValue: '' + searchValue: '', + + collapsed: false, + showSider: false, } list = [] @@ -108,16 +114,18 @@ export default class QueryTreeLayout extends Component { replaceFields = { value: 'id', title: 'title', - children: 'children' + children: 'children', } constructor(props) { super(props) this.autoLoad = typeof this.props.autoLoad === 'boolean' ? this.props.autoLoad : true - this.loadData = typeof this.props.loadData === 'function' ? this.props.loadData : async () => { } + this.loadData = + typeof this.props.loadData === 'function' ? this.props.loadData : async () => {} - this.defaultExpanded = typeof this.props.defaultExpanded === 'boolean' ? this.props.defaultExpanded : false + this.defaultExpanded = + typeof this.props.defaultExpanded === 'boolean' ? this.props.defaultExpanded : false if (this.props.replaceFields) { this.replaceFields = this.props.replaceFields @@ -131,6 +139,13 @@ export default class QueryTreeLayout extends Component { if (this.autoLoad) { this.onLoadData() } + + window.addEventListener('resize', this.onResizeLayout) + this.onResizeLayout() + } + + componentWillUnmount() { + window.removeEventListener('resize', this.onResizeLayout) } /** @@ -151,7 +166,7 @@ export default class QueryTreeLayout extends Component { } this.setState({ dataSource: data, - expandedKeys + expandedKeys, }) this.onLoaded() } @@ -162,8 +177,8 @@ export default class QueryTreeLayout extends Component { onLoading = () => { this.setState({ loading: { - indicator: - } + indicator: , + }, }) } @@ -178,28 +193,28 @@ export default class QueryTreeLayout extends Component { this.onLoadData() } - onExpand = (expandedKeys) => { + onExpand = expandedKeys => { this.setState({ expandedKeys, - autoExpandParent: false + autoExpandParent: false, }) } - onSelect = (selectedKeys) => { + onSelect = selectedKeys => { const selectedIds = [] selectedKeys.forEach(p => { const data = this.list.find(m => m.key === p) selectedIds.push(data[this.replaceFields.value]) }) this.setState({ - selectedKey: selectedIds[0] + selectedKey: selectedIds[0], }) if (this.props.onSelect) { this.props.onSelect(selectedIds[0]) } } - onSearch = (value) => { + onSearch = value => { const expandedKeys = this.list .map(p => { if (p[this.replaceFields.title].indexOf(value) > -1) { @@ -212,34 +227,49 @@ export default class QueryTreeLayout extends Component { this.setState({ expandedKeys, autoExpandParent: !!value, - searchValue: value + searchValue: value, + }) + } + + onResizeLayout = () => { + this.setState({ + collapsed: window.innerWidth <= SIDER_BREAK_POINT, }) } render() { - - const { dataSource, expandedKeys, autoExpandParent } = this.state + const { loading, dataSource, expandedKeys, autoExpandParent, collapsed, showSider } = + this.state const props = { treeData: dataSource, expandedKeys, - autoExpandParent + autoExpandParent, } const on = { - onExpand: (expandedKeys) => this.onExpand(expandedKeys), - onSelect: (selectedKeys) => this.onSelect(selectedKeys) + onExpand: expandedKeys => this.onExpand(expandedKeys), + onSelect: selectedKeys => this.onSelect(selectedKeys), } return ( - + p) + .join(' ')} + onMouseLeave={() => this.setState({ showSider: false })} + >
this.onSearch(value)} + onSearch={value => this.onSearch(value)} />
@@ -248,37 +278,56 @@ export default class QueryTreeLayout extends Component { this.onReloadData()} /> - this.setState({ expandedKeys: [] })} /> + this.setState({ expandedKeys: [] })} + />
- } wrapperClassName="h-100-p"> - { - !this.state.loading && !this.state.dataSource.length ? - - -

暂无数据

-
- } - description={false} - /> - : - renderTitle.call(this, nodeData)} - /> - } + } + wrapperClassName="h-100-p" + > + {!loading && !dataSource.length ? ( + + +

暂无数据

+
+ } + description={false} + /> + ) : ( + renderTitle.call(this, nodeData)} + /> + )} - - {renderBreadcrumbItem.call(this)} - + + {collapsed && ( + + + + + + )} + + + {this.state.taskStatus >= -1 && this.state.taskStatus < 3 && ( + + )} + {this.state.taskStatus == 2 && ( + + )} - diff --git a/web-react/src/pages/business/house/info/form/patrol/grade.jsx b/web-react/src/pages/business/house/info/form/patrol/grade.jsx index 6e23fc6..3dc1074 100644 --- a/web-react/src/pages/business/house/info/form/patrol/grade.jsx +++ b/web-react/src/pages/business/house/info/form/patrol/grade.jsx @@ -69,7 +69,8 @@ export default class handling extends Component { //#region 从后端转换成前段所需格式 if (this.record) { const { patrolInfo } = this.record - patrolInfo.initGrade = this.getInitGrade(getState('business').completedDate) + if (this.record.houseInfo.completedDate) + patrolInfo.initGrade = this.getInitGrade(getState('business').completedDate) } _state.codes = await getDictData( 'house_patrol_init_grade', @@ -130,19 +131,18 @@ export default class handling extends Component { - - - {codes.housePatrolInitGrade.map(item => { - return ( - - {item.value} - - ) - })} - - + + {codes.housePatrolInitGrade.map(item => { + return ( + + {item.value} + + ) + })} + 0 ? defaultRole[0] : '' - this.setState({ - lockRole: true, - }) + this.record.roleId = defaultRole[0] } else { this.record.roleId = defaultRole.id - this.setState({ - lockRole: defaultRole.code === 'zone_manager', - }) } + const lockRole = this.doLockRole(defaultRole) this.setState({ options: { - ...this.state.options, orgData, roleData, }, + lockRole, }) this.record = { @@ -141,6 +135,27 @@ export default class form extends Component { const { data } = await api.houseMemberDefaultRole({ orgId }) return data } + async onOrgChange(orgId) { + this.setState({ loading: true }) + const defaultRole = await this.loadDefaultRole(orgId) + const lockRole = this.doLockRole(defaultRole) + this.setState({ loading: false, lockRole }) + } + + doLockRole(defaultRole) { + if (defaultRole.constructor === Array) { + this.form.current.setFieldsValue({ + roleId: defaultRole[0].id, + }) + return true + } else { + this.form.current.setFieldsValue({ + roleId: defaultRole.id, + }) + return defaultRole.code === 'zone_manager' + } + } + render() { return (
@@ -156,6 +171,7 @@ export default class form extends Component { dropdownStyle={{ maxHeight: '300px', overflow: 'auto' }} treeDefaultExpandAll placeholder="请选择所属组织机构" + onChange={value => this.onOrgChange(value)} /> - this.onOpen(this.editForm, record)}>编辑 - , - - this.onDelete(record)} - > - 删除 - - , - - this.onResetPassword(record)}>重置密码 - , - - this.onOpen(this.dataForm, record)}>授权额外数据 - , + + + this.onOpen(this.editForm, id)}>编辑 + + + this.onDelete(id)} + > + 删除 + + + + this.onResetPassword(id)}>重置密码 + + + this.onOpen(this.dataForm, id)}>授权额外数据 + + , ]} > } /> - {record.roleCode && record.roleCode.includes('house_security_manager') && ( + {roleCode && roleCode.includes('house_security_manager') && ( +
} - footer={ - () => - - - - } + footer={() => ( + + + + )} /> - + diff --git a/web-react/src/pages/system/dict/index.jsx b/web-react/src/pages/system/dict/index.jsx index 7d6053a..8c46ab5 100644 --- a/web-react/src/pages/system/dict/index.jsx +++ b/web-react/src/pages/system/dict/index.jsx @@ -1,6 +1,14 @@ import React, { Component } from 'react' import { Button, Card, Form, Input, message as Message, Popconfirm, Radio } from 'antd' -import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions, QueryTreeLayout } from 'components' +import { + AntIcon, + Auth, + Container, + ModalForm, + QueryTable, + QueryTableActions, + QueryTreeLayout, +} from 'components' import { api } from 'common/api' import auth from 'components/authorized/handler' import { toCamelCase } from 'util/format' @@ -14,17 +22,16 @@ const apiAction = { page: api.sysDictTypePage, add: api.sysDictTypeAdd, edit: api.sysDictTypeEdit, - delete: api.sysDictTypeDelete + delete: api.sysDictTypeDelete, } const name = '字典' export default class index extends Component { - state = { codes: { - commonStatus: [] - } + commonStatus: [], + }, } // 表格实例 @@ -43,24 +50,29 @@ export default class index extends Component { { title: '字典名称', dataIndex: 'name', + width: 200, sorter: true, }, { title: '类型', key: 'type', dataIndex: 'code', + width: 120, sorter: true, - render: text => text ? '字典类型' : '目录' + render: text => (text ? '字典类型' : '目录'), }, { title: '唯一编码', dataIndex: 'code', + width: 120, sorter: true, }, { title: '排序', dataIndex: 'sort', + width: 80, sorter: true, + defaultSortOrder: 'ascend', }, { title: '备注', @@ -71,14 +83,15 @@ export default class index extends Component { { title: '状态', dataIndex: 'status', + width: 80, sorter: true, - render: text => this.bindCodeValue(text, 'common_status') + render: text => this.bindCodeValue(text, 'common_status'), }, ] /** * 构造函数,在渲染前动态添加操作字段等 - * @param {*} props + * @param {*} props */ constructor(props) { super(props) @@ -90,20 +103,22 @@ export default class index extends Component { title: '操作', width: 150, dataIndex: 'actions', - render: (text, record) => ( - - this.onOpen(this.editForm, record)}>编辑 - - - this.onDelete(record)} - > - 删除 - - - ) + render: (text, record) => ( + + + this.onOpen(this.editForm, record)}>编辑 + + + this.onDelete(record)} + > + 删除 + + + + ), }) } } @@ -112,9 +127,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -127,26 +142,28 @@ export default class index extends Component { componentDidMount() { this.table.current.onLoading() getDictData('common_status').then(res => { - this.setState({ - codes: res - }, () => { - this.table.current.onLoadData() - }) + this.setState( + { + codes: res, + }, + () => { + this.table.current.onLoadData() + } + ) }) } /** - * 调用加载数据接口,可在调用前对query进行处理 - * [异步,必要] - * @param {*} params - * @param {*} query - * @returns - */ + * 调用加载数据接口,可在调用前对query进行处理 + * [异步,必要] + * @param {*} params + * @param {*} query + * @returns + */ loadData = async (params, query) => { - query = { ...query, - pid: this.selectId + pid: this.selectId, } const { data } = await apiAction.page({ @@ -157,10 +174,10 @@ export default class index extends Component { } /** - * 调用树结构数据接口 - * [异步,必要] - * @returns - */ + * 调用树结构数据接口 + * [异步,必要] + * @returns + */ loadTreeData = async () => { const { data } = await apiAction.tree() return data @@ -169,7 +186,7 @@ export default class index extends Component { /** * 树节点选中事件 * [必要] - * @param {*} id + * @param {*} id */ onSelectTree(id) { this.selectId = id @@ -178,15 +195,15 @@ export default class index extends Component { /** * 绑定字典数据 - * @param {*} code - * @param {*} name - * @returns + * @param {*} code + * @param {*} name + * @returns */ bindCodeValue(code, name) { name = toCamelCase(name) const codes = this.state.codes[name] if (codes) { - const c = codes.find((p) => p.code == code) + const c = codes.find(p => p.code == code) if (c) { return c.value } @@ -196,21 +213,21 @@ export default class index extends Component { /** * 打开新增/编辑弹窗 - * @param {*} modal - * @param {*} record + * @param {*} modal + * @param {*} record */ onOpen(modal, record) { modal.current.open({ pid: this.selectId, - record + record, }) } /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -225,13 +242,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} record */ onDelete(record) { - this.onAction( - apiAction.delete(record), - '删除成功' - ) + this.onAction(apiAction.delete(record), '删除成功') } //#region 自定义方法 @@ -242,7 +256,7 @@ export default class index extends Component { this.onSelectTree(key)} + onSelect={key => this.onSelectTree(key)} > @@ -252,7 +266,7 @@ export default class index extends Component { loadData={this.loadData} columns={this.columns} queryInitialValues={{ - type: 2 + type: 2, }} query={ @@ -275,12 +289,14 @@ export default class index extends Component { + > + 新增{name} + } expandable={{ expandedRowRender: record => , - rowExpandable: record => !!record.code + rowExpandable: record => !!record.code, }} /> diff --git a/web-react/src/pages/system/log/oplog/index.jsx b/web-react/src/pages/system/log/oplog/index.jsx index 52bf8d0..6c18cd7 100644 --- a/web-react/src/pages/system/log/oplog/index.jsx +++ b/web-react/src/pages/system/log/oplog/index.jsx @@ -1,23 +1,42 @@ import React, { Component } from 'react' -import { Alert, Button, Card, Descriptions, Form, Popconfirm, Input, message as Message, Select, DatePicker } from 'antd' +import { + Alert, + Button, + Card, + Descriptions, + Form, + Popconfirm, + Input, + message as Message, + Select, + DatePicker, + Tag, +} from 'antd' import { Auth, Container, QueryTable } from 'components' import { api } from 'common/api' import { toCamelCase } from 'util/format' import { isEqual } from 'lodash' import getDictData from 'util/dic' import moment from 'moment' +import ReactJson from 'react-json-view' -const { RangePicker } = DatePicker; +const { RangePicker } = DatePicker const apiAction = { page: api.sysOpLogPage, - delete: api.sysOpLogDelete + delete: api.sysOpLogDelete, } + +const methodColor = { + POST: 'orange', + GET: 'green', +} + export default class index extends Component { state = { codes: { - opType: [] - } + opType: [], + }, } // 表格实例 table = React.createRef() @@ -26,37 +45,54 @@ export default class index extends Component { { title: '日志名称', dataIndex: 'name', - sorter: true, - }, - { - title: '操作类型', - dataIndex: 'opType', - render: text => (<>{this.bindCodeValue(text, 'op_type')}), - sorter: true, - }, - { - title: '是否成功', - dataIndex: 'success', - render: text => (<> {text ? '是' : '否'}), - sorter: true, - }, - { - title: 'ip', - dataIndex: 'ip', + width: 200, sorter: true, }, { title: '请求地址', dataIndex: 'url', + width: 300, + sorter: true, + render: (text, record) => ( + <> + + {record.reqMethod} + {' '} + {text} + + ), + }, + { + title: '是否成功', + dataIndex: 'success', + width: 100, + render: text => ( + <> + {text ? ( + + ) : ( + + )} + + ), + sorter: true, + }, + { + title: 'ip', + dataIndex: 'ip', + width: 120, sorter: true, }, { title: '操作时间', dataIndex: 'opTime', + width: 140, sorter: true, + defaultSortOrder: 'descend', }, { title: '操作人', + width: 140, dataIndex: 'account', sorter: true, }, @@ -66,9 +102,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -78,29 +114,20 @@ export default class index extends Component { * 加载字典数据,之后开始加载表格数据 * 如果必须要加载字典数据,可直接对表格设置autoLoad=true */ - componentDidMount() { - this.table.current.onLoading() - getDictData('op_type').then(res => { - this.setState({ - codes: res - }, () => { - this.table.current.onLoadData() - }) - }) - } + componentDidMount() {} /** * 调用加载数据接口,可在调用前对query进行处理 * [异步,必要] - * @param {*} params - * @param {*} query - * @returns + * @param {*} params + * @param {*} query + * @returns */ loadData = async (params, query) => { if (query.dates && query.dates.length) { - query.searchBeginTime = moment(query.dates[0]).format('YYYY-MM-DD HH:mm:ss'); - query.searchEndTime = moment(query.dates[1]).format('YYYY-MM-DD HH:mm:ss'); - delete query.dates; + query.searchBeginTime = moment(query.dates[0]).format('YYYY-MM-DD HH:mm:ss') + query.searchEndTime = moment(query.dates[1]).format('YYYY-MM-DD HH:mm:ss') + delete query.dates } const { data } = await apiAction.page({ ...params, @@ -109,16 +136,16 @@ export default class index extends Component { return data } /** - * 绑定字典数据 - * @param {*} code - * @param {*} name - * @returns - */ + * 绑定字典数据 + * @param {*} code + * @param {*} name + * @returns + */ bindCodeValue(code, name) { name = toCamelCase(name) const codes = this.state.codes[name] if (codes) { - const c = codes.find((p) => +p.code === code) + const c = codes.find(p => +p.code === code) if (c) { return c.value } @@ -129,8 +156,8 @@ export default class index extends Component { /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -144,27 +171,27 @@ export default class index extends Component { } onOpLogClear() { - this.onAction( - apiAction.delete(), - '清空成功' - ) + this.onAction(apiAction.delete(), '清空成功') } render() { return (
- -
后端bug:任何操作的操作类型都是增加
-
没有记录请求参数.返回结果等信息
- - } /> + +
后端bug:任何操作的操作类型都是增加
+
没有记录请求参数.返回结果等信息
+ + } + />
- - - - + > } @@ -222,8 +231,8 @@ export default class index extends Component { } expandable={{ - expandedRowRender: record => - + expandedRowRender: record => ( + {record.methodName} @@ -240,20 +249,26 @@ export default class index extends Component { {record.className} - {record.result} + - {record.param} + {record.message} + ), }} - />
) } -} \ No newline at end of file +} diff --git a/web-react/src/pages/system/log/vislog/index.jsx b/web-react/src/pages/system/log/vislog/index.jsx index ea0f940..3f5cafa 100644 --- a/web-react/src/pages/system/log/vislog/index.jsx +++ b/web-react/src/pages/system/log/vislog/index.jsx @@ -1,5 +1,16 @@ import React, { Component } from 'react' -import { Alert, Button, Card, Descriptions, Form, Popconfirm, Input, message as Message, Select, DatePicker } from 'antd' +import { + Alert, + Button, + Card, + Descriptions, + Form, + Popconfirm, + Input, + message as Message, + Select, + DatePicker, +} from 'antd' import { Auth, Container, QueryTable } from 'components' import { api } from 'common/api' import { toCamelCase } from 'util/format' @@ -7,17 +18,17 @@ import { isEqual } from 'lodash' import getDictData from 'util/dic' import moment from 'moment' -const { RangePicker } = DatePicker; +const { RangePicker } = DatePicker const apiAction = { page: api.sysVisLogPage, - delete: api.sysVisLogDelete + delete: api.sysVisLogDelete, } export default class index extends Component { state = { codes: { - visType: [] - } + visType: [], + }, } // 表格实例 table = React.createRef() @@ -26,38 +37,54 @@ export default class index extends Component { { title: '日志名称', dataIndex: 'name', + width: 200, sorter: true, }, { title: '访问类型', dataIndex: 'visType', - render: text => (<>{this.bindCodeValue(text, 'vis_type')}), + width: 120, + render: text => <>{this.bindCodeValue(text, 'vis_type')}, sorter: true, }, { title: '是否成功', dataIndex: 'success', - render: text => (<> {text ? '是' : '否'}), + width: 120, + render: text => ( + <> + {text ? ( + + ) : ( + + )} + + ), sorter: true, }, { title: 'ip', dataIndex: 'ip', + width: 180, sorter: true, }, { title: '浏览器', dataIndex: 'browser', + width: 180, sorter: true, }, { title: '访问时间', dataIndex: 'visTime', + width: 180, sorter: true, + defaultSortOrder: 'descend', }, { title: '访问人', dataIndex: 'account', + width: 180, sorter: true, }, ] @@ -66,9 +93,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -81,26 +108,29 @@ export default class index extends Component { componentDidMount() { this.table.current.onLoading() getDictData('vis_type').then(res => { - this.setState({ - codes: res - }, () => { - this.table.current.onLoadData() - }) + this.setState( + { + codes: res, + }, + () => { + this.table.current.onLoadData() + } + ) }) } /** * 调用加载数据接口,可在调用前对query进行处理 * [异步,必要] - * @param {*} params - * @param {*} query - * @returns + * @param {*} params + * @param {*} query + * @returns */ loadData = async (params, query) => { if (query.dates && query.dates.length) { - query.searchBeginTime = moment(query.dates[0]).format('YYYY-MM-DD HH:mm:ss'); - query.searchEndTime = moment(query.dates[1]).format('YYYY-MM-DD HH:mm:ss'); - delete query.dates; + query.searchBeginTime = moment(query.dates[0]).format('YYYY-MM-DD HH:mm:ss') + query.searchEndTime = moment(query.dates[1]).format('YYYY-MM-DD HH:mm:ss') + delete query.dates } const { data } = await apiAction.page({ ...params, @@ -109,16 +139,16 @@ export default class index extends Component { return data } /** - * 绑定字典数据 - * @param {*} code - * @param {*} name - * @returns - */ + * 绑定字典数据 + * @param {*} code + * @param {*} name + * @returns + */ bindCodeValue(code, name) { name = toCamelCase(name) const codes = this.state.codes[name] if (codes) { - const c = codes.find((p) => +p.code === code) + const c = codes.find(p => +p.code === code) if (c) { return c.value } @@ -129,8 +159,8 @@ export default class index extends Component { /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -144,17 +174,18 @@ export default class index extends Component { } onVisLogClear() { - this.onAction( - apiAction.delete(), - '清空成功' - ) + this.onAction(apiAction.delete(), '清空成功') } render() { return (
- +
- - + > } @@ -220,16 +245,22 @@ export default class index extends Component { } expandable={{ - expandedRowRender: record => - - + expandedRowRender: record => ( + + {record.message} + ), }} />
) } -} \ No newline at end of file +} diff --git a/web-react/src/pages/system/menu/form.jsx b/web-react/src/pages/system/menu/form.jsx index 83f9b8f..bbc7dea 100644 --- a/web-react/src/pages/system/menu/form.jsx +++ b/web-react/src/pages/system/menu/form.jsx @@ -7,29 +7,31 @@ import { api } from 'common/api' import { EMPTY_ID } from 'util/global' const initialValues = { - type: '1', - openType: '1', + type: 1, + openType: 1, + weight: '2', visible: true, - sort: 100 + sort: 100, } export default class form extends Component { - state = { // 加载状态 loading: true, codes: { menuType: [], - openType: [] + openType: [], + menuWeight: [], }, options: { appList: [], - parentTreeData: [] + parentTreeData: [], }, + addType: [], type: initialValues.type, openType: initialValues.openType, - icon: '' + icon: '', } // 表单实例 @@ -51,45 +53,49 @@ export default class form extends Component { * 填充数据 * 可以在设置this.record之后对其作出数据结构调整 * [异步,必要] - * @param {*} params + * @param {*} params */ async fillData(params) { + const form = this.form.current this.record = cloneDeep(params.record) //#region 从后端转换成前段所需格式 - const { menuType, openType } = await getDictData('menu_type', 'open_type') + const codes = await getDictData('menu_type', 'open_type', 'menu_weight') const appList = await this.onLoadSysApplist() let parentTreeData = [] if (params.isParent) { parentTreeData = await this.onLoadMenuTree(params.parent.application) - } else if (params.record) { + } + + if (params.record) { parentTreeData = await this.onLoadMenuTree(params.record.application) + } else { + this.setState({ addType: params.addType }) + if (params.addType.length) { + form.setFieldsValue({ + type: params.addType[0], + }) + } } const icon = params.record && params.record.icon this.setState({ - codes: { - menuType, - openType - }, + codes, options: { appList, - parentTreeData + parentTreeData, }, - icon + icon, }) //#endregion - const form = this.form.current if (params.isParent) { form.setFieldsValue({ pid: params.parent.id, - application: params.parent.application + application: params.parent.application, }) } else { form.setFieldsValue(this.record) } - this.setState({ - loading: false - }) + this.setState({ loading: false }) this.onTypeChange() } @@ -98,7 +104,7 @@ export default class form extends Component { * 获取数据 * 可以对postData进行数据结构调整 * [异步,必要] - * @returns + * @returns */ async getData() { const form = this.form.current @@ -123,30 +129,31 @@ export default class form extends Component { async onLoadMenuTree(application) { const { data } = await api.getMenuTree({ application }) - return [{ - id: EMPTY_ID, - parentId: undefined, - title: '顶级', - value: EMPTY_ID, - pid: undefined, - children: data, - }] + return [ + { + id: EMPTY_ID, + parentId: undefined, + title: '顶级', + value: EMPTY_ID, + pid: undefined, + children: data, + }, + ] } - onTypeChange() { this.onTypeChangeGroup() - const form = this.form.current - const { type } = form.getFieldsValue() - if (['0', '2'].includes(type)) { - form.setFieldsValue({ - openType: '0' - }) - } else { - form.setFieldsValue({ - openType: '1' - }) - } + // const form = this.form.current + // const { type } = form.getFieldsValue() + // if ([0, 2].includes(type)) { + // form.setFieldsValue({ + // openType: 0, + // }) + // } else { + // form.setFieldsValue({ + // openType: 1, + // }) + // } } onOpenTypeChange() { @@ -168,178 +175,221 @@ export default class form extends Component { this.setState({ type, - openType + openType, }) } async onApplicationChange(value) { this.setState({ - loading: true + loading: true, }) const parentTreeData = await this.onLoadMenuTree(value) this.setState({ loading: false, options: { ...this.state.options, - parentTreeData - } + parentTreeData, + }, }) this.form.current.setFieldsValue({ - pid: undefined + pid: undefined, }) } onSelectIcon(icon) { this.form.current.setFieldsValue({ - icon + icon, }) this.setState({ icon }) } //#endregion render() { + const { loading, codes, options, addType, type, openType, icon } = this.state + return ( -
- }> + + }>

基本信息

- 目录:默认添加在顶级 -
菜单: -
按钮: + 目录:一级菜单,默认添加在顶级 +
+ 菜单:二级菜单 +
+ 按钮:菜单中对应到接口的功能 } rules={[{ required: true, message: '请选择菜单类型' }]} > - this.onTypeChange(e)}> - { - this.state.codes.menuType.map(item => { - return ( - {item.value} - ) - }) - } + this.onTypeChange(e)}> + {codes.menuType.map(item => { + return ( + + {item.value} + + ) + })}
- + - - this.onApplicationChange(value)} + > + {options.appList.map(item => { + return ( + + {item.name} + + ) + })} - { - this.state.type != 0 && - + {type != 0 && ( + - } + )} + + 系统权重:菜单/功能任何角色可用 +
+ 业务权重:菜单/功能为超级管理员不可用,可防止管理员误操作 + + } + rules={[{ required: true, message: '请选择权重' }]} + > + + {codes.menuWeight.map(item => { + return ( + + {item.value} + + ) + })} + +

扩展信息

- { - this.state.type == 1 && + {type == 1 && ( - this.onOpenTypeChange(e)}> - { - this.state.codes.openType.map(item => { - return ( - {item.value} - ) - }) - } + this.onOpenTypeChange(e)}> + {codes.openType.map(item => { + return ( + + {item.value} + + ) + })} - } - { - this.state.type == 1 && this.state.openType == 1 && - + )} + {type == 1 && openType == 1 && ( + - } - { - this.state.type == 1 && this.state.openType == 2 && - + )} + {type == 1 && openType == 2 && ( + - } - { - this.state.type == 1 && this.state.openType == 3 && - + )} + {type == 1 && openType == 3 && ( + - } - { - this.state.type == 2 && - + )} + {type == 2 && ( + - } - { - this.state.type == 2 && - + )} + {type == 2 && ( + - } + )} - { - this.state.type != 2 && + {type != 2 && ( - } + addonBefore={icon && } addonAfter={ - this - .iconSelector - .current - .open(this.form.current.getFieldValue('icon')) + this.iconSelector.current.open( + this.form.current.getFieldValue('icon') + ) } /> } /> - } + )} - this.onSelectIcon(icon)} /> + this.onSelectIcon(icon)} /> ) } diff --git a/web-react/src/pages/system/menu/index.jsx b/web-react/src/pages/system/menu/index.jsx index 27eaaf9..a7566f3 100644 --- a/web-react/src/pages/system/menu/index.jsx +++ b/web-react/src/pages/system/menu/index.jsx @@ -1,5 +1,5 @@ import React, { Component } from 'react' -import { Button, Table, Card, Popconfirm, message as Message, Row, Col, Tooltip } from 'antd' +import { Button, Table, Card, Popconfirm, message as Message, Row, Col, Tooltip, Tag } from 'antd' import { isEqual } from 'lodash' import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } from 'components' import { api } from 'common/api' @@ -24,6 +24,7 @@ export default class index extends Component { codes: { menuType: [], menuWeight: [], + openType: [], }, } @@ -55,9 +56,36 @@ export default class index extends Component { render: text => text && , }, { - title: '前端组件', + title: '连接', width: 220, - dataIndex: 'component', + dataIndex: 'openType', + render: (text, record) => { + switch (text) { + case 1: + return ( + <> + {this.bindCodeValue(text, 'open_type')}{' '} + {record.component} + + ) + case 2: + return ( + <> + {this.bindCodeValue(text, 'open_type')}{' '} + {record.link} + + ) + case 3: + return ( + <> + {this.bindCodeValue(text, 'open_type')}{' '} + {record.redirect} + + ) + default: + return '' + } + }, }, { title: '排序', @@ -83,7 +111,9 @@ export default class index extends Component { render: (text, record) => ( - this.onOpen(this.editForm, record)}>编辑 + this.onOpen({ modal: this.editForm, record })}> + 编辑 + {record.type < 2 && ( - this.onOpen(this.addForm, record, true)}> + + this.onOpen({ + modal: this.addForm, + record, + isParent: true, + addType: record.type == 0 ? [1] : [2], + }) + } + > {record.type == 0 ? '新增子菜单' : '新增功能'} @@ -125,7 +164,7 @@ export default class index extends Component { */ componentDidMount() { this.table.current.onLoading() - getDictData('menu_type', 'menu_weight').then(res => { + getDictData('menu_type', 'menu_weight', 'open_type').then(res => { this.setState( { codes: res, @@ -162,7 +201,7 @@ export default class index extends Component { name = toCamelCase(name) const codes = this.state.codes[name] if (codes) { - const c = codes.find(p => p.code === code) + const c = codes.find(p => p.code == code) if (c) { return c.value } @@ -175,15 +214,17 @@ export default class index extends Component { * @param {*} modal * @param {*} record */ - onOpen(modal, record, isParent = false) { + onOpen({ modal, record, isParent = false, addType = [] }) { const params = isParent ? { parent: record, isParent, + addType, } : { record, isParent, + addType, } modal.current.open(params) @@ -246,7 +287,9 @@ export default class index extends Component { this.onOpen(this.editForm, item)} + onClick={() => + this.onOpen({ modal: this.editForm, record: item }) + } > @@ -280,9 +323,12 @@ export default class index extends Component { if (isFunction) { grids.push( this.onOpen(this.addForm, record, true)} + onClick={() => + this.onOpen({ modal: this.addForm, record, isParent: true, addType: [2] }) + } >
@@ -331,9 +377,11 @@ export default class index extends Component { } diff --git a/web-react/src/pages/system/org/index.jsx b/web-react/src/pages/system/org/index.jsx index ad00a84..431e063 100644 --- a/web-react/src/pages/system/org/index.jsx +++ b/web-react/src/pages/system/org/index.jsx @@ -1,6 +1,14 @@ import React, { Component } from 'react' import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd' -import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions, QueryTreeLayout } from 'components' +import { + AntIcon, + Auth, + Container, + ModalForm, + QueryTable, + QueryTableActions, + QueryTreeLayout, +} from 'components' import { api } from 'common/api' import auth from 'components/authorized/handler' import { toCamelCase } from 'util/format' @@ -13,17 +21,16 @@ const apiAction = { page: api.getOrgPage, add: api.sysOrgAdd, edit: api.sysOrgEdit, - delete: api.sysOrgDelete + delete: api.sysOrgDelete, } const name = '机构' export default class index extends Component { - state = { codes: { - orgType: [] - } + orgType: [], + }, } // 树框架实例 @@ -44,13 +51,13 @@ export default class index extends Component { columns = [ { title: '机构名称', - width: '400px', + width: 400, dataIndex: 'name', sorter: true, }, { title: '唯一编码', - width: '200px', + width: 200, dataIndex: 'code', sorter: true, }, @@ -58,24 +65,26 @@ export default class index extends Component { title: '机构类型', dataIndex: 'type', sorter: true, - render: text => (<>{this.bindCodeValue(text, 'org_type')}) + render: text => <>{this.bindCodeValue(text, 'org_type')}, }, { title: '排序', - width: '80px', + width: 80, dataIndex: 'sort', sorter: true, + defaultSortOrder: 'ascend', }, { title: '备注', dataIndex: 'remark', + width: 400, sorter: true, }, ] /** * 构造函数,在渲染前动态添加操作字段等 - * @param {*} props + * @param {*} props */ constructor(props) { super(props) @@ -87,20 +96,22 @@ export default class index extends Component { title: '操作', width: 150, dataIndex: 'actions', - render: (text, record) => ( - - this.onOpen(this.editForm, record)}>编辑 - - - this.onDelete(record)} - > - 删除 - - - ) + render: (text, record) => ( + + + this.onOpen(this.editForm, record)}>编辑 + + + this.onDelete(record)} + > + 删除 + + + + ), }) } } @@ -109,9 +120,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -124,26 +135,28 @@ export default class index extends Component { componentDidMount() { this.table.current.onLoading() getDictData('org_type').then(res => { - this.setState({ - codes: res - }, () => { - this.table.current.onLoadData() - }) + this.setState( + { + codes: res, + }, + () => { + this.table.current.onLoadData() + } + ) }) } /** * 调用加载数据接口,可在调用前对query进行处理 * [异步,必要] - * @param {*} params - * @param {*} query - * @returns + * @param {*} params + * @param {*} query + * @returns */ loadData = async (params, query) => { - query = { ...query, - pid: this.selectId + pid: this.selectId, } const { data } = await apiAction.page({ @@ -166,7 +179,7 @@ export default class index extends Component { /** * 树节点选中事件 * [必要] - * @param {*} id + * @param {*} id */ onSelectTree(id) { this.selectId = id @@ -175,15 +188,15 @@ export default class index extends Component { /** * 绑定字典数据 - * @param {*} code - * @param {*} name - * @returns + * @param {*} code + * @param {*} name + * @returns */ bindCodeValue(code, name) { name = toCamelCase(name) const codes = this.state.codes[name] if (codes) { - const c = codes.find((p) => p.code === code) + const c = codes.find(p => p.code == code) if (c) { return c.value } @@ -193,21 +206,21 @@ export default class index extends Component { /** * 打开新增/编辑弹窗 - * @param {*} modal - * @param {*} record + * @param {*} modal + * @param {*} record */ onOpen(modal, record) { modal.current.open({ orgId: this.selectId, - record + record, }) } /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -227,13 +240,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} record */ onDelete(record) { - this.onAction( - apiAction.delete(record), - '删除成功' - ) + this.onAction(apiAction.delete(record), '删除成功') } //#region 自定义方法 @@ -245,7 +255,7 @@ export default class index extends Component { ref={this.treeLayout} loadData={this.loadTreeData} defaultExpanded={true} - onSelect={(key) => this.onSelectTree(key)} + onSelect={key => this.onSelectTree(key)} > @@ -265,7 +275,9 @@ export default class index extends Component { + > + 新增{name} + } /> diff --git a/web-react/src/pages/system/pos/index.jsx b/web-react/src/pages/system/pos/index.jsx index c12f74c..e59dda6 100644 --- a/web-react/src/pages/system/pos/index.jsx +++ b/web-react/src/pages/system/pos/index.jsx @@ -2,24 +2,22 @@ import React, { Component } from 'react' import { Button, Card, Form, Input, Popconfirm, message as Message } from 'antd' import { isEqual } from 'lodash' import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } from 'components' -import { api } from "common/api" +import { api } from 'common/api' import auth from 'components/authorized/handler' import FormBody from './form' - // 配置页面所需接口函数 const apiAction = { page: api.sysPosPage, add: api.sysPosAdd, edit: api.sysPosEdit, - delete: api.sysPosDelete + delete: api.sysPosDelete, } // 用于弹窗标题 const name = '职位' export default class index extends Component { - // 表格实例 table = React.createRef() @@ -32,29 +30,34 @@ export default class index extends Component { { title: '职位名称', dataIndex: 'name', + width: 400, sorter: true, }, { title: '唯一编码', dataIndex: 'code', + width: 400, sorter: true, }, { title: '排序', dataIndex: 'sort', + width: 80, sorter: true, + defaultSortOrder: 'ascend', }, { title: '备注', dataIndex: 'remark', + width: 400, sorter: true, }, ] /** - * 构造函数,在渲染前动态添加操作字段等 - * @param {*} props - */ + * 构造函数,在渲染前动态添加操作字段等 + * @param {*} props + */ constructor(props) { super(props) @@ -65,20 +68,22 @@ export default class index extends Component { title: '操作', width: 150, dataIndex: 'actions', - render: (text, record) => ( - - this.onOpen(this.editForm, record)}>编辑 - - - this.onDelete(record)} - > - 删除 - - - ) + render: (text, record) => ( + + + this.onOpen(this.editForm, record)}>编辑 + + + this.onDelete(record)} + > + 删除 + + + + ), }) } } @@ -87,9 +92,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -98,9 +103,9 @@ export default class index extends Component { /** * 调用加载数据接口,可在调用前对query进行处理 * [异步,必要] - * @param {*} params - * @param {*} query - * @returns + * @param {*} params + * @param {*} query + * @returns */ loadData = async (params, query) => { const { data } = await apiAction.page({ @@ -111,21 +116,21 @@ export default class index extends Component { } /** - * 打开新增/编辑弹窗 - * @param {*} modal - * @param {*} record - */ + * 打开新增/编辑弹窗 + * @param {*} modal + * @param {*} record + */ onOpen(modal, record) { modal.current.open({ - record + record, }) } /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -140,13 +145,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} record */ onDelete(record) { - this.onAction( - apiAction.delete(record), - '删除成功' - ) + this.onAction(apiAction.delete(record), '删除成功') } render() { @@ -172,11 +174,11 @@ export default class index extends Component { + > + 新增{name} + } - > - - + > ) } -} \ No newline at end of file +} diff --git a/web-react/src/pages/system/role/index.jsx b/web-react/src/pages/system/role/index.jsx index e9edb04..865db78 100644 --- a/web-react/src/pages/system/role/index.jsx +++ b/web-react/src/pages/system/role/index.jsx @@ -16,14 +16,13 @@ const apiAction = { delete: api.sysRoleDelete, grantMenu: api.sysRoleGrantMenu, - grantData: api.sysRoleGrantData + grantData: api.sysRoleGrantData, } // 用于弹窗标题 const name = '角色' export default class index extends Component { - // 表格实例 table = React.createRef() @@ -39,23 +38,27 @@ export default class index extends Component { { title: '角色名', dataIndex: 'name', + width: 400, sorter: true, }, { title: '唯一编码', dataIndex: 'code', + width: 400, sorter: true, }, { title: '排序', dataIndex: 'sort', + width: 80, sorter: true, - } + defaultSortOrder: 'ascend', + }, ] /** * 构造函数,在渲染前动态添加操作字段等 - * @param {*} props + * @param {*} props */ constructor(props) { super(props) @@ -67,44 +70,58 @@ export default class index extends Component { title: '操作', width: 150, dataIndex: 'actions', - render: (text, record) => ( - - this.onOpen(this.editForm, record)}>编辑 - - - this.onDelete(record)} - > - 删除 - - - - - - - this.onOpen(this.menuForm, record)}>授权菜单 - - - - - this.onOpen(this.dataForm, record)}>授权数据 - - - - } - > - - 授权 - - - - - ) + render: (text, record) => ( + + + this.onOpen(this.editForm, record)}>编辑 + + + this.onDelete(record)} + > + 删除 + + + + + + + + this.onOpen(this.menuForm, record) + } + > + 授权菜单 + + + + + + + this.onOpen(this.dataForm, record) + } + > + 授权数据 + + + + + } + > + + 授权 + + + + + + ), }) } } @@ -113,9 +130,9 @@ export default class index extends Component { * 阻止外部组件引发的渲染,提升性能 * 可自行添加渲染条件 * [必要] - * @param {*} props - * @param {*} state - * @returns + * @param {*} props + * @param {*} state + * @returns */ shouldComponentUpdate(props, state) { return !isEqual(this.state, state) @@ -124,9 +141,9 @@ export default class index extends Component { /** * 调用加载数据接口,可在调用前对query进行处理 * [异步,必要] - * @param {*} params - * @param {*} query - * @returns + * @param {*} params + * @param {*} query + * @returns */ loadData = async (params, query) => { const { data } = await apiAction.page({ @@ -138,20 +155,20 @@ export default class index extends Component { /** * 打开新增/编辑弹窗 - * @param {*} modal - * @param {*} record + * @param {*} modal + * @param {*} record */ onOpen(modal, record) { modal.current.open({ - record + record, }) } /** * 对表格上的操作进行统一处理 * [异步] - * @param {*} action - * @param {*} successMessage + * @param {*} action + * @param {*} successMessage */ async onAction(action, successMessage) { this.table.current.onLoading() @@ -166,13 +183,10 @@ export default class index extends Component { /** * 删除 - * @param {*} record + * @param {*} record */ onDelete(record) { - this.onAction( - apiAction.delete(record), - '删除成功' - ) + this.onAction(apiAction.delete(record), '删除成功') } //#region 自定义方法 @@ -202,7 +216,9 @@ export default class index extends Component { + > + 新增{name} + } /> diff --git a/web-react/src/pages/system/user/data.jsx b/web-react/src/pages/system/user/data.jsx index 88f6a0d..2e5d0b7 100644 --- a/web-react/src/pages/system/user/data.jsx +++ b/web-react/src/pages/system/user/data.jsx @@ -20,7 +20,7 @@ export default class data extends Component { form = React.createRef() // 初始化数据 - record = {} + id = '' /** * mount后回调 @@ -29,11 +29,11 @@ export default class data extends Component { this.props.created && this.props.created(this) } async fillData(params) { - this.record = cloneDeep(params.record) + this.id = params.id //#region 从后端转换成前段所需格式 const orgData = await this.loadOrgData() const areaData = await this.loadAreaData() - const orgCheckedKeys = await this.loadMemberOwn(this.record.id) + const orgCheckedKeys = await this.loadMemberOwn(this.id) this.setState({ options: { orgData, @@ -42,7 +42,7 @@ export default class data extends Component { }, }) this.form.current.setFieldsValue({ - id: this.record.id, + id: this.id, grantOrgIdList: orgCheckedKeys, grantAreaCodeList: [], }) @@ -63,8 +63,8 @@ export default class data extends Component { const valid = await form.validateFields() if (valid) { const postData = form.getFieldsValue() - if (this.record) { - postData.id = this.record.id + if (this.id) { + postData.id = this.id } //#region 从前段转换后端所需格式 //#endregion diff --git a/web-react/src/pages/system/user/form.jsx b/web-react/src/pages/system/user/form.jsx index b8eed13..204c88a 100644 --- a/web-react/src/pages/system/user/form.jsx +++ b/web-react/src/pages/system/user/form.jsx @@ -1,5 +1,17 @@ import React, { Component } from 'react' -import { Button, Row, Col, Form, Input, DatePicker, Radio, Table, Select, Spin, TreeSelect } from 'antd' +import { + Button, + Row, + Col, + Form, + Input, + DatePicker, + Radio, + Table, + Select, + Spin, + TreeSelect, +} from 'antd' import { AntIcon } from 'components' import { cloneDeep } from 'lodash' import getDictData from 'util/dic' @@ -9,25 +21,24 @@ import moment from 'moment' const initialValues = { sex: 0, - sysEmpParam: {} + sysEmpParam: {}, } export default class form extends Component { - state = { // 加载状态 loading: true, codes: { - orgType: [] + orgType: [], }, options: { orgData: [], - posData: [] + posData: [], }, sysEmpParam: { - extIds: [] - } + extIds: [], + }, } extColumns = [ { @@ -45,7 +56,7 @@ export default class form extends Component { placeholder="请选择附加组织机构" /> - ) + ), }, { title: '附属岗位', @@ -56,33 +67,28 @@ export default class form extends Component { - ) + ), }, { title: '操作', key: 'action', width: '70px', render: (text, record) => ( - - ) + ), }, ] // 表单实例 @@ -102,11 +108,13 @@ export default class form extends Component { * 填充数据 * 可以在设置this.record之后对其作出数据结构调整 * [异步,必要] - * @param {*} params + * @param {*} params */ async fillData(params) { - this.record = cloneDeep(params.record || {}) //#region 从后端转换成前段所需格式 + if (params.id) { + this.record = (await api.sysUserDetail({ id: params.id })).data + } const orgData = await this.loadOrgData() const posData = await this.loadPosData() const codes = await getDictData('org_type') @@ -118,17 +126,17 @@ export default class form extends Component { // 提交的时候是"param",而获取下来却是"info",在这里转换一下 if (this.record.sysEmpInfo) { - this.record.sysEmpParam = this.record.sysEmpInfo; - delete this.record.sysEmpInfo; + this.record.sysEmpParam = this.record.sysEmpInfo + delete this.record.sysEmpInfo } else if (!this.record.sysEmpParam) { this.record.sysEmpParam = { extIds: [], - }; + } } // 转换职位信息列表 if (this.record.sysEmpParam.positions) { - this.record.sysEmpParam.posIdList = this.record.sysEmpParam.positions.map((p) => p.posId); + this.record.sysEmpParam.posIdList = this.record.sysEmpParam.positions.map(p => p.posId) } // 附加信息 @@ -138,12 +146,12 @@ export default class form extends Component { key: i, orgId: p.orgId, posId: p.posId, - }; - }); + } + }) } if (params.orgId) { - this.record.sysEmpParam.orgId = params.orgId; + this.record.sysEmpParam.orgId = params.orgId } this.setState({ @@ -154,18 +162,18 @@ export default class form extends Component { posData, }, sysEmpParam: { - ...this.record.sysEmpParam - } + ...this.record.sysEmpParam, + }, }) this.record = { - ...this.record + ...this.record, } //#endregion this.form.current.setFieldsValue(this.record) this.setState({ - loading: false + loading: false, }) } @@ -173,7 +181,7 @@ export default class form extends Component { * 获取数据 * 可以对postData进行数据结构调整 * [异步,必要] - * @returns + * @returns */ async getData() { const form = this.form.current @@ -206,24 +214,26 @@ export default class form extends Component { const record = { key: extIds.length > 0 ? extIds[extIds.length - 1].key + 1 : 0, orgId: undefined, - posId: undefined + posId: undefined, } - this.setState({ - sysEmpParam: { - extIds: [...extIds, record] + this.setState( + { + sysEmpParam: { + extIds: [...extIds, record], + }, + }, + () => { + console.log(this.form.current.getFieldsValue()) } - }, () => { - console.log(this.form.current.getFieldsValue()) - }) - + ) } onRemoveExtData(record) { const ext = this.state.sysEmpParam.extIds, - remove = ext.find((p) => p.key === record.key), - index = ext.indexOf(remove); + remove = ext.find(p => p.key === record.key), + index = ext.indexOf(remove) - ext.splice(index, 1); + ext.splice(index, 1) console.log(ext) // this.form.current.setFieldsValue({ @@ -232,14 +242,16 @@ export default class form extends Component { // } // }) - this.setState({ - sysEmpParam: { - extIds: ext + this.setState( + { + sysEmpParam: { + extIds: ext, + }, + }, + () => { + //console.log(this.form.current.getFieldsValue()) } - }, () => { - //console.log(this.form.current.getFieldsValue()) - }) - + ) } //#endregion renderExtInfoTable() { @@ -251,79 +263,100 @@ export default class form extends Component { pagination={false} size="small" bordered - rowKey={(record) => record.key} - footer={ - () => - - } - > - + rowKey={record => record.key} + footer={() => ( + + )} + > ) } render() { return ( -
- }> + + }>

基本信息

- + - + - {this.props.mode == 'add' && <> - - - - - - - - } - + {this.props.mode == 'add' && ( + <> + + + + + + + + )} + - + - - + + 保密 - + - + - + - + - +
@@ -332,7 +365,8 @@ export default class form extends Component { + rules={[{ required: true, message: '所属组织机构' }]} + > - - + + - + {this.state.options.posData.map(item => { + return ( + + {item.name} + + ) + })}
diff --git a/web-react/src/pages/system/user/index.jsx b/web-react/src/pages/system/user/index.jsx index 7418764..080b4e0 100644 --- a/web-react/src/pages/system/user/index.jsx +++ b/web-react/src/pages/system/user/index.jsx @@ -21,6 +21,7 @@ import getDictData from 'util/dic' import FormBody from './form' import RoleForm from './role' import DataForm from './data' +import auth from 'components/authorized/handler' // 配置页面所需接口函数 const apiAction = { @@ -154,12 +155,12 @@ export default class index extends Component { /** * 打开新增/编辑弹窗 * @param {*} modal - * @param {*} record + * @param {*} id */ - onOpen(modal, record) { + onOpen(modal, id) { modal.current.open({ orgId: this.selectId, - record, + id, }) } @@ -190,44 +191,45 @@ export default class index extends Component { //#region 自定义方法 renderItem(record) { + const { id, account, name, nickName, avatar, sex, phone, email, status } = record return ( - this.onOpen(this.editForm, record)}>编辑 + this.onOpen(this.editForm, id)}>编辑
, this.onDelete(record)} + onConfirm={() => this.onDelete(id)} > 删除 , - this.onResetPassword(record)}>重置密码 + this.onResetPassword(id)}>重置密码 , - + - - - this.onOpen(this.roleForm, record)}> + {auth('sysUser:grantRole') && ( + + this.onOpen(this.roleForm, id)}> 授权角色 - - - - this.onOpen(this.dataForm, record)}> + )} + {auth('sysUser:grantData') && ( + + this.onOpen(this.dataForm, id)}> 授权额外数据 - + )} } > @@ -245,29 +247,28 @@ export default class index extends Component { type="avatar" shape="square" size={48} - id={record.avatar} + id={avatar} icon={} /> } - title={record.nickName || record.name} - description={record.account} + title={nickName || name} + description={account} /> - {this.bindCodeValue(record.sex, 'sex')} + {this.bindCodeValue(sex, 'sex')} - {record.phone || '未设置'} - {record.email || '未设置'} + {phone || '未设置'} + {email || '未设置'}
this.onSetUserStatus(record, checked)} + onChange={checked => this.onSetUserStatus(id, checked)} />
@@ -276,12 +277,12 @@ export default class index extends Component { ) } - onSetUserStatus(record, checked) { - this.onAction(apiAction.changeStatus({ id: record.id, status: +!checked }), '设置成功') + onSetUserStatus(id, checked) { + this.onAction(apiAction.changeStatus({ id, status: +!checked }), '设置成功') } - onResetPassword(record) { - this.onAction(apiAction.resetPwd(record), '重置成功') + onResetPassword(id) { + this.onAction(apiAction.resetPwd({ id }), '重置成功') } //#endregion diff --git a/web-react/src/pages/system/user/role.jsx b/web-react/src/pages/system/user/role.jsx index beb472b..131cc68 100644 --- a/web-react/src/pages/system/user/role.jsx +++ b/web-react/src/pages/system/user/role.jsx @@ -19,7 +19,7 @@ export default class role extends Component { form = React.createRef() // 初始化数据 - record = {} + id = '' /** * mount后回调 @@ -28,10 +28,10 @@ export default class role extends Component { this.props.created && this.props.created(this) } async fillData(params) { - this.record = cloneDeep(params.record) + this.id = params.id //#region 从后端转换成前段所需格式 const roleData = await this.loadRoleData() - const roles = await this.loadRole(this.record.id) + const roles = await this.loadRole(this.id) this.setState({ options: { roleData, @@ -39,7 +39,7 @@ export default class role extends Component { roles, }) this.form.current.setFieldsValue({ - id: this.record.id, + id: this.id, grantRoleIdList: roles, }) @@ -59,8 +59,8 @@ export default class role extends Component { const valid = await form.validateFields() if (valid) { const postData = form.getFieldsValue() - if (this.record) { - postData.id = this.record.id + if (this.id) { + postData.id = this.id } //#region 从前段转换后端所需格式 //#endregion diff --git a/web-react/src/store/reducer/layout.js b/web-react/src/store/reducer/layout.js index 7f2fa41..1441e84 100644 --- a/web-react/src/store/reducer/layout.js +++ b/web-react/src/store/reducer/layout.js @@ -1,6 +1,21 @@ -const layout = (state = { - siderCollapsed: false -}, action) => { +import { SETTING_KEY } from "common/storage" +import { SIDER_BREAK_POINT } from "util/global" + +const defaultState = { + siderCollapsed: false, + allowSiderCollapsed: true +} + +const localStorageState = () => { + return JSON.parse(window.localStorage.getItem(SETTING_KEY)) || {} +} + +const mergeState = { + ...defaultState, + ...localStorageState() +} + +const layout = (state = mergeState, action) => { switch (action.type) { // 打开窗口 case 'OPEN_WINDOW': @@ -13,8 +28,23 @@ const layout = (state = { return state // 侧边收起状态 case 'TOGGLE_COLLAPSED': - const _state = { ...state, siderCollapsed: action.siderCollapsed } - return _state + { + if (window.innerWidth <= SIDER_BREAK_POINT) { + return state + } + const _state = { ...state, siderCollapsed: action.siderCollapsed } + window.localStorage.setItem(SETTING_KEY, JSON.stringify(_state)) + return _state + } + case 'AUTO_TOGGLE_COLLAPSED': + { + const _state = { + ...state, + siderCollapsed: localStorageState().siderCollapsed || action.siderCollapsed, + allowSiderCollapsed: !action.siderCollapsed + } + return _state + } default: return state } diff --git a/web-react/src/util/global/index.js b/web-react/src/util/global/index.js index 2543e20..918cb47 100644 --- a/web-react/src/util/global/index.js +++ b/web-react/src/util/global/index.js @@ -36,4 +36,6 @@ export const RSA_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQU /** * 城市名称 */ -export const CITY = '黄石市' \ No newline at end of file +export const CITY = '黄石市' + +export const SIDER_BREAK_POINT = 1366 \ No newline at end of file diff --git a/web-react/src/views/main/_layout/content/index.jsx b/web-react/src/views/main/_layout/content/index.jsx index 73f2ad5..e52b045 100644 --- a/web-react/src/views/main/_layout/content/index.jsx +++ b/web-react/src/views/main/_layout/content/index.jsx @@ -20,7 +20,6 @@ class ComponentDynamic extends Component { if (this.props.onRef) { this.props.onRef(this) } - return true } @@ -73,6 +72,40 @@ class ComponentDynamic extends Component { } } +class Iframe extends Component { + shouldComponentUpdate() { + if (this.props.onRef) { + this.props.onRef(this) + } + return true + } + + componentDidMount() { + if (this.props.onRef) { + this.props.onRef(this) + } + this.loadComponent() + } + + loadComponent() { + NProgress.start() + const iframe = this.refs.content + iframe.onload = () => { + NProgress.done() + } + iframe.onerror = () => { + NProgress.done() + } + iframe.src = this.props.src + } + + render() { + const { title } = this.props + + return