From fd9665c265ccad9160218677acc009a9124ab5a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?=
<188633308@qq.com>
Date: Fri, 25 Jun 2021 17:59:09 +0800
Subject: [PATCH 1/5] =?UTF-8?q?update=20=E5=93=8D=E5=BA=94=E5=BC=8F?=
=?UTF-8?q?=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web-react/src/assets/style/lib/list.less | 42 ++++-
web-react/src/assets/style/lib/table.less | 8 +
.../src/assets/style/lib/tree-layout.less | 14 ++
web-react/src/components/query-list/index.jsx | 56 ++++++-
.../components/query-tree-layout/index.jsx | 157 ++++++++++++------
web-react/src/store/reducer/layout.js | 40 ++++-
web-react/src/util/global/index.js | 4 +-
.../src/views/main/_layout/header/index.jsx | 13 +-
web-react/src/views/main/index.jsx | 13 +-
9 files changed, 275 insertions(+), 72 deletions(-)
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/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 && (
-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 && (
+
+ }
+ onClick={() => this.setState({ showSider: true })}
+ />
+
+ )}
+
+
+ {renderBreadcrumbItem.call(this)}
+
+
+
{this.props.children}
diff --git a/web-react/src/store/reducer/layout.js b/web-react/src/store/reducer/layout.js
index 7f2fa41..aeadbee 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/header/index.jsx b/web-react/src/views/main/_layout/header/index.jsx
index c0e0b01..ccf9f9d 100644
--- a/web-react/src/views/main/_layout/header/index.jsx
+++ b/web-react/src/views/main/_layout/header/index.jsx
@@ -33,13 +33,20 @@ export default class index extends Component {
}
render() {
+ const { allowSiderCollapsed } = this.state
+
return (
-
this.onCollapsed()}>
-
-
+ {allowSiderCollapsed && (
+
this.onCollapsed()}
+ >
+
+
+ )}
diff --git a/web-react/src/views/main/index.jsx b/web-react/src/views/main/index.jsx
index 665c59f..1e7e7eb 100644
--- a/web-react/src/views/main/index.jsx
+++ b/web-react/src/views/main/index.jsx
@@ -1,10 +1,9 @@
import React, { Component } from 'react'
import { Spin, Layout } from 'antd'
-import { LoadingOutlined } from '@ant-design/icons'
import { api } from 'common/api'
import { cloneDeep, groupBy, findIndex, last } from 'lodash'
import store from 'store'
-import { EMPTY_ID } from 'util/global'
+import { EMPTY_ID, SIDER_BREAK_POINT } from 'util/global'
import Header from './_layout/header'
import Sider from './_layout/sider'
@@ -83,6 +82,9 @@ export default class index extends Component {
})
})
})
+
+ window.addEventListener('resize', this.onResizeSider)
+ this.onResizeSider()
}
/**
@@ -231,6 +233,13 @@ export default class index extends Component {
})
}
+ onResizeSider = () => {
+ dispatch({
+ type: 'AUTO_TOGGLE_COLLAPSED',
+ siderCollapsed: window.innerWidth <= SIDER_BREAK_POINT,
+ })
+ }
+
render() {
const { loading, panes, actived } = this.state
From f27e3956b97b0cfda18f587e59eb2f7dc71a871c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?=
<188633308@qq.com>
Date: Mon, 28 Jun 2021 13:19:26 +0800
Subject: [PATCH 2/5] =?UTF-8?q?update=20=E6=93=8D=E4=BD=9C=E6=97=A5?=
=?UTF-8?q?=E5=BF=97=E5=AE=8C=E5=96=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Api/Ewide.Core/Filter/RequestActionFilter.cs | 27 ++-
Api/Ewide.Core/Service/Auth/AuthService.cs | 32 +--
Api/Ewide.Core/Service/Log/SysOpLogService.cs | 13 +-
Api/Ewide.Core/Service/Menu/SysMenuService.cs | 2 +-
web-react/package.json | 3 +-
.../src/components/query-table/index.jsx | 2 +-
.../src/pages/system/log/oplog/index.jsx | 209 ++++++++++--------
web-react/src/pages/system/user/index.jsx | 15 +-
web-react/src/store/reducer/layout.js | 2 +-
.../src/views/main/_layout/sider/menu.jsx | 38 ++--
web-react/yarn.lock | 139 +++++++++++-
11 files changed, 334 insertions(+), 148 deletions(-)
diff --git a/Api/Ewide.Core/Filter/RequestActionFilter.cs b/Api/Ewide.Core/Filter/RequestActionFilter.cs
index fa6ce44..6c441ee 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.();
}
}
}
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/SysMenuService.cs b/Api/Ewide.Core/Service/Menu/SysMenuService.cs
index fa73ffa..2a79991 100644
--- a/Api/Ewide.Core/Service/Menu/SysMenuService.cs
+++ b/Api/Ewide.Core/Service/Menu/SysMenuService.cs
@@ -84,7 +84,7 @@ namespace Ewide.Core.Service
.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.Weight != (int)MenuWeight.DEFAULT_WEIGHT)
.OrderBy(u => u.Sort).ToListAsync();
}
else
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/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/pages/system/log/oplog/index.jsx b/web-react/src/pages/system/log/oplog/index.jsx
index 52bf8d0..3a9b794 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,14 @@ export default class index extends Component {
}
expandable={{
- expandedRowRender: record =>
-
+ expandedRowRender: record => (
+
{record.methodName}
@@ -240,20 +255,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/user/index.jsx b/web-react/src/pages/system/user/index.jsx
index 7418764..f40c684 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 = {
@@ -209,25 +210,25 @@ export default class index extends Component {
this.onResetPassword(record)}>重置密码
,
-
+
-
-
+ {auth('sysUser:grantRole') && (
+
this.onOpen(this.roleForm, record)}>
授权角色
-
-
-
+ )}
+ {auth('sysUser:grantData') && (
+
this.onOpen(this.dataForm, record)}>
授权额外数据
-
+ )}
}
>
diff --git a/web-react/src/store/reducer/layout.js b/web-react/src/store/reducer/layout.js
index aeadbee..1441e84 100644
--- a/web-react/src/store/reducer/layout.js
+++ b/web-react/src/store/reducer/layout.js
@@ -7,7 +7,7 @@ const defaultState = {
}
const localStorageState = () => {
- return JSON.parse(window.localStorage.getItem(SETTING_KEY))
+ return JSON.parse(window.localStorage.getItem(SETTING_KEY)) || {}
}
const mergeState = {
diff --git a/web-react/src/views/main/_layout/sider/menu.jsx b/web-react/src/views/main/_layout/sider/menu.jsx
index 4d91304..f20f406 100644
--- a/web-react/src/views/main/_layout/sider/menu.jsx
+++ b/web-react/src/views/main/_layout/sider/menu.jsx
@@ -6,9 +6,8 @@ import store from 'store'
const { getState, subscribe } = store
export default class index extends Component {
-
state = {
- ...getState('nav')
+ ...getState('nav'),
}
constructor(props) {
@@ -23,21 +22,25 @@ export default class index extends Component {
this.unsubscribe()
}
- renderMenu = (menu) => {
- return menu.map((p) => {
+ renderMenu = menu => {
+ return menu.map(p => {
return p.children ? this.renderSubMenu(p) : this.renderMenuItem(p)
})
}
- renderSubMenu = (menu) => {
+ renderSubMenu = menu => {
return (
- }>
+ }
+ >
{this.renderMenu(menu.children)}
)
}
- renderMenuItem = (menu) => {
+ renderMenuItem = menu => {
return (
this.onOpenContentWindow(menu)}>
{menu.meta.icon && }
@@ -46,12 +49,12 @@ export default class index extends Component {
)
}
- onOpenContentWindow = (menu) => {
+ onOpenContentWindow = menu => {
window.openContentWindow({
key: menu.id,
title: menu.meta.title,
icon: menu.meta.icon,
- path: menu.component
+ path: menu.component,
})
}
@@ -60,12 +63,11 @@ export default class index extends Component {
}
render() {
-
const props = {
mode: 'inline',
selectable: false,
style: this.props.menuStyle,
- theme: 'light'
+ theme: 'light',
}
const on = {
@@ -74,16 +76,20 @@ export default class index extends Component {
return (
<>
- {
- this.state.nav.map((item, i) => {
+ {this.state.nav.map((item, i) => {
+ if (item.menu.length) {
return (
{item.app.name}
-
+
)
- })
- }
+ } else {
+ return false
+ }
+ })}
>
)
}
diff --git a/web-react/yarn.lock b/web-react/yarn.lock
index c0cf4a2..cad1a03 100644
--- a/web-react/yarn.lock
+++ b/web-react/yarn.lock
@@ -2554,7 +2554,7 @@ arrify@^2.0.1:
resolved "https://registry.nlark.com/arrify/download/arrify-2.0.1.tgz?cache=0&sync_timestamp=1619599497996&other_urls=https%3A%2F%2Fregistry.nlark.com%2Farrify%2Fdownload%2Farrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
integrity sha1-yWVekzHgq81YjSp8rX6ZVvZnAfo=
-asap@~2.0.6:
+asap@~2.0.3, asap@~2.0.6:
version "2.0.6"
resolved "https://registry.nlark.com/asap/download/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
@@ -2852,6 +2852,11 @@ balanced-match@^1.0.0:
resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.2.tgz?cache=0&sync_timestamp=1617714233441&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbalanced-match%2Fdownload%2Fbalanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=
+base16@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npm.taobao.org/base16/download/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
+ integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=
+
base64-js@^1.0.2:
version "1.5.1"
resolved "https://registry.nlark.com/base64-js/download/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@@ -3752,6 +3757,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+cross-fetch@^3.0.4:
+ version "3.1.4"
+ resolved "https://registry.npm.taobao.org/cross-fetch/download/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
+ integrity sha1-lyPzo6JHv4uJA586OAqSROj6Lzk=
+ dependencies:
+ node-fetch "2.6.1"
+
cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz?cache=0&sync_timestamp=1606748073153&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcross-spawn%2Fdownload%2Fcross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@@ -5086,6 +5098,31 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
+fbemitter@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npm.taobao.org/fbemitter/download/fbemitter-3.0.0.tgz#00b2a1af5411254aab416cd75f9e6289bee4bff3"
+ integrity sha1-ALKhr1QRJUqrQWzXX55iib7kv/M=
+ dependencies:
+ fbjs "^3.0.0"
+
+fbjs-css-vars@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.npm.taobao.org/fbjs-css-vars/download/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
+ integrity sha1-IWVRE2rgL+JVkyw+yHdfGOLAeLg=
+
+fbjs@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npm.taobao.org/fbjs/download/fbjs-3.0.0.tgz?cache=0&sync_timestamp=1602048886093&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffbjs%2Fdownload%2Ffbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165"
+ integrity sha1-CQcGf7P1enj0XZXx6s/8rNYjwWU=
+ dependencies:
+ cross-fetch "^3.0.4"
+ fbjs-css-vars "^1.0.0"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.18"
+
figgy-pudding@^3.5.1:
version "3.5.2"
resolved "https://registry.nlark.com/figgy-pudding/download/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
@@ -5212,6 +5249,14 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
+flux@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.npm.taobao.org/flux/download/flux-4.0.1.tgz#7843502b02841d4aaa534af0b373034a1f75ee5c"
+ integrity sha1-eENQKwKEHUqqU0rws3MDSh917lw=
+ dependencies:
+ fbemitter "^3.0.0"
+ fbjs "^3.0.0"
+
follow-redirects@^1.0.0, follow-redirects@^1.10.0:
version "1.14.1"
resolved "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
@@ -7137,11 +7182,21 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.nlark.com/lodash.clonedeep/download/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
+lodash.curry@^4.0.1:
+ version "4.1.1"
+ resolved "https://registry.npm.taobao.org/lodash.curry/download/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
+ integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA=
+
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.npm.taobao.org/lodash.debounce/download/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
+lodash.flow@^3.3.0:
+ version "3.5.0"
+ resolved "https://registry.npm.taobao.org/lodash.flow/download/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
+ integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=
+
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.nlark.com/lodash.memoize/download/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -7639,6 +7694,11 @@ no-case@^3.0.4:
lower-case "^2.0.2"
tslib "^2.0.3"
+node-fetch@2.6.1:
+ version "2.6.1"
+ resolved "https://registry.nlark.com/node-fetch/download/node-fetch-2.6.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fnode-fetch%2Fdownload%2Fnode-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
+ integrity sha1-BFvTI2Mfdu0uK1VXM5RBa2OaAFI=
+
node-forge@^0.10.0:
version "0.10.0"
resolved "https://registry.npm.taobao.org/node-forge/download/node-forge-0.10.0.tgz?cache=0&sync_timestamp=1599010726129&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-forge%2Fdownload%2Fnode-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
@@ -9040,6 +9100,13 @@ promise-inflight@^1.0.1:
resolved "https://registry.nlark.com/promise-inflight/download/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.npm.taobao.org/promise/download/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ integrity sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=
+ dependencies:
+ asap "~2.0.3"
+
promise@^8.1.0:
version "8.1.0"
resolved "https://registry.npm.taobao.org/promise/download/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e"
@@ -9142,6 +9209,11 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.nlark.com/punycode/download/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha1-tYsBCsQMIsVldhbI0sLALHv0eew=
+pure-color@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.npm.taobao.org/pure-color/download/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e"
+ integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=
+
q@^1.1.2:
version "1.5.1"
resolved "https://registry.nlark.com/q/download/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -9576,6 +9648,16 @@ react-app-polyfill@^2.0.0:
regenerator-runtime "^0.13.7"
whatwg-fetch "^3.4.1"
+react-base16-styling@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.npm.taobao.org/react-base16-styling/download/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c"
+ integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=
+ dependencies:
+ base16 "^1.0.0"
+ lodash.curry "^4.0.1"
+ lodash.flow "^3.3.0"
+ pure-color "^1.2.0"
+
react-dev-utils@^11.0.3:
version "11.0.4"
resolved "https://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-11.0.4.tgz?cache=0&sync_timestamp=1615231838520&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dev-utils%2Fdownload%2Freact-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
@@ -9630,6 +9712,21 @@ react-is@^17.0.1:
resolved "https://registry.nlark.com/react-is/download/react-is-17.0.2.tgz?cache=0&sync_timestamp=1623273254569&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-is%2Fdownload%2Freact-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA=
+react-json-view@^1.21.3:
+ version "1.21.3"
+ resolved "https://registry.npm.taobao.org/react-json-view/download/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475"
+ integrity sha1-8YQgnujxvzdPsMQbCBPP9UVJxHU=
+ dependencies:
+ flux "^4.0.1"
+ react-base16-styling "^0.6.0"
+ react-lifecycles-compat "^3.0.4"
+ react-textarea-autosize "^8.3.2"
+
+react-lifecycles-compat@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.npm.taobao.org/react-lifecycles-compat/download/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
+ integrity sha1-TxonOv38jzSIqMUWv9p4+HI1I2I=
+
react-monaco-editor@^0.43.0:
version "0.43.0"
resolved "https://registry.npm.taobao.org/react-monaco-editor/download/react-monaco-editor-0.43.0.tgz#495578470db7b27ab306af813b31f206a6bf9d1c"
@@ -9738,6 +9835,15 @@ react-scripts@4.0.3:
optionalDependencies:
fsevents "^2.1.3"
+react-textarea-autosize@^8.3.2:
+ version "8.3.3"
+ resolved "https://registry.nlark.com/react-textarea-autosize/download/react-textarea-autosize-8.3.3.tgz?cache=0&sync_timestamp=1622628433420&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-textarea-autosize%2Fdownload%2Freact-textarea-autosize-8.3.3.tgz#f70913945369da453fd554c168f6baacd1fa04d8"
+ integrity sha1-9wkTlFNp2kU/1VTBaPa6rNH6BNg=
+ dependencies:
+ "@babel/runtime" "^7.10.2"
+ use-composed-ref "^1.0.0"
+ use-latest "^1.0.0"
+
react@^17.0.2:
version "17.0.2"
resolved "https://registry.nlark.com/react/download/react-17.0.2.tgz?cache=0&sync_timestamp=1623272232595&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact%2Fdownload%2Freact-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
@@ -10387,7 +10493,7 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3"
split-string "^3.0.1"
-setimmediate@^1.0.4:
+setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.nlark.com/setimmediate/download/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
@@ -11220,6 +11326,11 @@ tryer@^1.0.1:
resolved "https://registry.npm.taobao.org/tryer/download/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
integrity sha1-8shUBoALmw90yfdGW4HqrSQSUvg=
+ts-essentials@^2.0.3:
+ version "2.0.12"
+ resolved "https://registry.nlark.com/ts-essentials/download/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745"
+ integrity sha1-yTA/PXT3X6dSjD1JuA4ImrCdh0U=
+
ts-pnp@1.2.0, ts-pnp@^1.1.6:
version "1.2.0"
resolved "https://registry.npm.taobao.org/ts-pnp/download/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
@@ -11336,6 +11447,11 @@ typedarray@^0.0.6:
resolved "https://registry.nlark.com/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
+ua-parser-js@^0.7.18:
+ version "0.7.28"
+ resolved "https://registry.nlark.com/ua-parser-js/download/ua-parser-js-0.7.28.tgz#8ba04e653f35ce210239c64661685bf9121dec31"
+ integrity sha1-i6BOZT81ziECOcZGYWhb+RId7DE=
+
unbox-primitive@^1.0.1:
version "1.0.1"
resolved "https://registry.npm.taobao.org/unbox-primitive/download/unbox-primitive-1.0.1.tgz?cache=0&sync_timestamp=1616706302651&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funbox-primitive%2Fdownload%2Funbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
@@ -11480,6 +11596,25 @@ url@^0.11.0:
punycode "1.3.2"
querystring "0.2.0"
+use-composed-ref@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.npm.taobao.org/use-composed-ref/download/use-composed-ref-1.1.0.tgz#9220e4e94a97b7b02d7d27eaeab0b37034438bbc"
+ integrity sha1-kiDk6UqXt7AtfSfq6rCzcDRDi7w=
+ dependencies:
+ ts-essentials "^2.0.3"
+
+use-isomorphic-layout-effect@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.npm.taobao.org/use-isomorphic-layout-effect/download/use-isomorphic-layout-effect-1.1.1.tgz#7bb6589170cd2987a152042f9084f9effb75c225"
+ integrity sha1-e7ZYkXDNKYehUgQvkIT57/t1wiU=
+
+use-latest@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.npm.taobao.org/use-latest/download/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232"
+ integrity sha1-pE9lcrgojgly7EEb3QhAraNm8jI=
+ dependencies:
+ use-isomorphic-layout-effect "^1.0.0"
+
use@^3.1.0:
version "3.1.1"
resolved "https://registry.nlark.com/use/download/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
From 6d4d69eeb6d81ab1da821ae907354964f478386f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?=
<188633308@qq.com>
Date: Mon, 28 Jun 2021 13:21:26 +0800
Subject: [PATCH 3/5] =?UTF-8?q?update=20=E5=90=8C=E4=B8=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Api/Ewide.Core/Filter/RequestActionFilter.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Api/Ewide.Core/Filter/RequestActionFilter.cs b/Api/Ewide.Core/Filter/RequestActionFilter.cs
index 6c441ee..de89d27 100644
--- a/Api/Ewide.Core/Filter/RequestActionFilter.cs
+++ b/Api/Ewide.Core/Filter/RequestActionFilter.cs
@@ -73,7 +73,7 @@ namespace Ewide.Core
OpTime = DateTime.Now,
Account = httpContext.User?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT)
};
- await sysOpLog.();
+ await sysOpLog.InsertAsync();
}
}
}
From f1ae3d5b2a9c3aac1825ea8416ef1039f3ac2fa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?=
<188633308@qq.com>
Date: Mon, 28 Jun 2021 13:47:59 +0800
Subject: [PATCH 4/5] =?UTF-8?q?fix=20=E8=8F=9C=E5=8D=95=E6=8E=88=E6=9D=83?=
=?UTF-8?q?=E9=80=89=E6=8B=A9=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/components/authority-view/index.jsx | 99 ++++++++++---------
1 file changed, 53 insertions(+), 46 deletions(-)
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)}
+
+ )
+ })}
+
+ ) : (
+
+ )}
)
From 6dceac060d7ed7a6e7769d019abba0224cf50fb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?=
<188633308@qq.com>
Date: Mon, 28 Jun 2021 17:23:47 +0800
Subject: [PATCH 5/5] =?UTF-8?q?update=20=E5=BC=BA=E5=8C=96=E8=8F=9C?=
=?UTF-8?q?=E5=8D=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Api/Ewide.Core/Enum/MenuType.cs | 6 +-
Api/Ewide.Core/Ewide.Core.xml | 16 +-
Api/Ewide.Core/Filter/RequestActionFilter.cs | 2 +-
.../Service/Menu/Dto/AntDesignTreeNode.cs | 7 +-
Api/Ewide.Core/Service/Menu/Dto/MenuInput.cs | 12 +-
Api/Ewide.Core/Service/Menu/SysMenuService.cs | 66 ++--
web-react/src/assets/style/main.less | 8 +
web-react/src/components/modal-form/index.jsx | 103 +++---
web-react/src/pages/system/menu/form.jsx | 316 ++++++++++--------
web-react/src/pages/system/menu/index.jsx | 72 +++-
.../src/views/main/_layout/content/index.jsx | 60 +++-
.../src/views/main/_layout/header/search.jsx | 16 +-
.../src/views/main/_layout/sider/menu.jsx | 22 +-
web-react/src/views/main/index.jsx | 28 +-
14 files changed, 491 insertions(+), 243 deletions(-)
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 de89d27..6a37036 100644
--- a/Api/Ewide.Core/Filter/RequestActionFilter.cs
+++ b/Api/Ewide.Core/Filter/RequestActionFilter.cs
@@ -73,7 +73,7 @@ namespace Ewide.Core
OpTime = DateTime.Now,
Account = httpContext.User?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT)
};
- await sysOpLog.InsertAsync();
+ await sysOpLog.InsertNowAsync();
}
}
}
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 2a79991..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,7 +83,7 @@ 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.Type != (int)MenuType.FUNCTION)
.Where(u => u.Weight != (int)MenuWeight.DEFAULT_WEIGHT)
.OrderBy(u => u.Sort).ToListAsync();
}
@@ -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/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/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/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 (
-