wenlele
1 year ago
26 changed files with 952 additions and 89 deletions
@ -0,0 +1,164 @@ |
|||
'use strict'; |
|||
const Hex = require('crypto-js/enc-hex'); |
|||
const MD5 = require('crypto-js/md5'); |
|||
|
|||
function getUserList(opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
const models = ctx.fs.dc.models; |
|||
const { page, limit, name, role } = ctx.query; |
|||
const Op = ctx.fs.dc.ORM.Op; |
|||
let errMsg = { message: '获取用户失败' } |
|||
try { |
|||
let searchWhere = { |
|||
username: { $not: 'SuperAdmin' } |
|||
} |
|||
let option = { |
|||
where: searchWhere, |
|||
order: [["id", "desc"]], |
|||
attributes: { exclude: ['password'] }, |
|||
} |
|||
|
|||
if (name) { |
|||
searchWhere.name = { $like: '%' + name + '%' }; |
|||
} |
|||
|
|||
if (role) { |
|||
searchWhere.role = role; |
|||
} |
|||
|
|||
option.where = searchWhere |
|||
let limit_ = limit || 10; |
|||
let page_ = page || 1; |
|||
let offset = (page_ - 1) * limit_; |
|||
if (limit && page) { |
|||
option.limit = limit_ |
|||
option.offset = offset |
|||
} |
|||
|
|||
const res = await models.User.findAndCount(option); |
|||
ctx.status = 200; |
|||
ctx.body = res; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = errMsg |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 新增用户
|
|||
function addUser(opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
const models = ctx.fs.dc.models; |
|||
try { |
|||
const { username } = ctx.request.body |
|||
const checkName = await models.User.findOne({ where: { username } }); |
|||
if (checkName) { |
|||
ctx.status = 400; |
|||
ctx.body = { message: "该用户名已存在" } |
|||
} else { |
|||
let rslt = ctx.request.body; |
|||
rslt.password = 'e10adc3949ba59abbe56e057f20f883e'; |
|||
await models.User.create(Object.assign({}, rslt)) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '新建用户成功' } |
|||
} |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '新建用户失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改用户
|
|||
function editUser(opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
try { |
|||
const models = ctx.fs.dc.models; |
|||
const { id } = ctx.params; |
|||
const body = ctx.request.body; |
|||
if (body.oldpassword) { |
|||
const password = Hex.stringify(MD5(body.oldpassword)); |
|||
const checkPwd = await models.User.findOne({ where: { id: id, password } }); |
|||
if (!checkPwd) { |
|||
ctx.status = 400; |
|||
ctx.body = { message: '旧密码错误' } |
|||
} else { |
|||
await models.User.update( |
|||
{ password: Hex.stringify(MD5(body.password)) }, |
|||
{ where: { id: id, } } |
|||
) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '修改用户成功' } |
|||
} |
|||
} else { |
|||
const checkName = await models.User.findOne({ where: { id: { $not: id }, username: body.username } }); |
|||
if (checkName) { |
|||
ctx.status = 400; |
|||
ctx.body = { message: '该用户名已存在' } |
|||
} else { |
|||
await models.User.update( |
|||
body, |
|||
{ where: { id: id, } } |
|||
) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '修改用户成功' } |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '修改用户失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 删除用户
|
|||
function deleteUser(opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
try { |
|||
const models = ctx.fs.dc.models; |
|||
const { id } = ctx.params; |
|||
|
|||
const checkName1 = await models.MetadataDatabase.findOne({ where: { createBy: id } }); |
|||
const checkName2 = await models.MetadataFile.findOne({ where: { createBy: id } }); |
|||
const checkName3 = await models.MetadataRestapi.findOne({ where: { createBy: id } }); |
|||
if (checkName1 || checkName2 || checkName3) { |
|||
ctx.status = 400; |
|||
ctx.body = { message: '该用户下存在依赖资源无法删除!' } |
|||
} else { |
|||
await models.User.destroy({ |
|||
where: { |
|||
id: id |
|||
} |
|||
}) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '删除用户成功' } |
|||
} |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '删除用户失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
module.exports = { |
|||
getUserList, |
|||
addUser, |
|||
editUser, |
|||
deleteUser, |
|||
|
|||
} |
@ -0,0 +1,23 @@ |
|||
'use strict'; |
|||
|
|||
const member = require('../../controllers/member/index'); |
|||
|
|||
module.exports = function (app, router, opts, AuthCode) { |
|||
|
|||
app.fs.api.logAttr['POST/meta/member'] = { content: '增加用户', visible: true }; |
|||
router.post('/meta/member', member.addUser(opts)) |
|||
|
|||
// 修改用户信息
|
|||
app.fs.api.logAttr['PUT/meta/member/:id'] = { content: '修改用户信息', visible: true }; |
|||
router.put('/meta/member/:id', member.editUser(opts)) |
|||
|
|||
// 删除用户信息
|
|||
app.fs.api.logAttr['DEL/meta/member/:id'] = { content: '删除用户信息', visible: true }; |
|||
router.del('/meta/member/:id', member.deleteUser(opts)) |
|||
|
|||
//获取用户信息列表
|
|||
app.fs.api.logAttr['GET/meta/members'] = { content: '获取用户信息列表', visible: true }; |
|||
router.get('/meta/members', member.getUserList(opts)); |
|||
|
|||
|
|||
}; |
@ -0,0 +1,4 @@ |
|||
alter table t_user |
|||
add enabled boolean default true; |
|||
|
|||
comment on column t_user.enabled is '是否启用'; |
@ -0,0 +1,6 @@ |
|||
'use strict'; |
|||
|
|||
import * as member from './member'; |
|||
export default { |
|||
...member |
|||
} |
@ -0,0 +1,56 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getUserList(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query || {}, |
|||
actionType: 'GET_MEMBER_REPORT', |
|||
url: `${ApiTable.getUserList}`, |
|||
msg: { error: '获取用户列表失败' }, |
|||
reducer: { name: 'member' } |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function addUser(params) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'ADD_MEMBER_REPORT', |
|||
url: ApiTable.addUser, |
|||
msg: { |
|||
option: '用户新增', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
export function deleteUser(id) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'del', |
|||
dispatch, |
|||
actionType: 'DELETE_MEMBER_REPORT', |
|||
url: ApiTable.modifyUser.replace('{id}', id), |
|||
msg: { |
|||
option: '用户删除', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
export function modifyUser(id, params, msg) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'put', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'MODIFY_MEMBER_REPORT', |
|||
url: ApiTable.modifyUser.replace('{id}', id), |
|||
msg: { |
|||
option: msg || '用户编辑', |
|||
}, |
|||
}); |
|||
} |
|||
|
@ -0,0 +1,69 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function addTask(params, msg) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'ADD_ACQ_TASK', |
|||
url: ApiTable.addTask, |
|||
msg: { |
|||
option: msg || '新增采集任务', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
export function getTasks(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query || {}, |
|||
actionType: 'GET_ACQ_TASKS', |
|||
url: `${ApiTable.getTasks}`, |
|||
msg: { error: '获取采集任务列表失败' }, |
|||
reducer: { name: 'tasks' } |
|||
}); |
|||
} |
|||
|
|||
export function deleteTask(id) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'del', |
|||
dispatch, |
|||
actionType: 'DELETE_ACQ_TASK', |
|||
url: ApiTable.modifyTask.replace('{id}', id), |
|||
msg: { |
|||
option: '采集任务删除', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
export function modifyTask(id, params, msg) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'put', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'MODIFY_ACQ_TASK', |
|||
url: ApiTable.modifyTask.replace('{id}', id), |
|||
msg: { |
|||
option: msg || '采集任务编辑', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
export function runTask(params, msg) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'RUN_ACQ_TASK', |
|||
url: ApiTable.runTask, |
|||
msg: { |
|||
option: msg || '任务执行', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
|
@ -0,0 +1,78 @@ |
|||
import React, { useRef } from 'react'; |
|||
import { Button, Form } from 'antd'; |
|||
import { InfoCircleOutlined } from '@ant-design/icons'; |
|||
import { |
|||
ModalForm, |
|||
ProFormSelect, |
|||
ProFormTextArea, |
|||
ProFormDigit, |
|||
ProFormText, |
|||
ProFormSwitch |
|||
} from '@ant-design/pro-form'; |
|||
|
|||
export default (props) => { |
|||
const { title, triggerRender, editData = null, onFinish, paramsName } = props; |
|||
const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } }; |
|||
const initialValues = editData ? { |
|||
...editData, |
|||
} : {}; |
|||
const [form] = Form.useForm(); |
|||
const formRef = useRef(); |
|||
return ( |
|||
<ModalForm |
|||
formRef={formRef} |
|||
title={title || ''} |
|||
initialValues={initialValues} |
|||
trigger={ |
|||
triggerRender ? triggerRender : <Button type="primary" > |
|||
{title || ''} |
|||
</Button> |
|||
} |
|||
layout="horizontal" |
|||
grid={true} |
|||
{...formItemLayout} |
|||
modalProps={{ |
|||
destroyOnClose: true, |
|||
onCancel: () => { }, |
|||
}} |
|||
onFinish={async (values) => { |
|||
return onFinish && await onFinish(values, editData, form) |
|||
// return true;
|
|||
}} |
|||
width={500} |
|||
> |
|||
<ProFormText |
|||
rules={[{ required: true, message: '请输入姓名' }, |
|||
{ max: 255, message: '姓名长度不能大于255个字符' }, |
|||
]} |
|||
name="name" |
|||
label="姓名" |
|||
/> |
|||
|
|||
<ProFormText |
|||
rules={[{ required: true, message: '请输入用户名' }, |
|||
{ max: 255, message: '用户名长度不能大于255个字符' }, |
|||
]} |
|||
name="username" |
|||
label="用户名" |
|||
/> |
|||
|
|||
<ProFormSelect |
|||
disabled={editData} |
|||
rules={[{ required: true, message: '请选择角色' }]} |
|||
options={[ |
|||
{ label: '系统管理员', value: '系统管理员' }, |
|||
{ label: '数据消费者', value: '数据消费者' }, |
|||
]} |
|||
name="role" |
|||
label="角色" |
|||
/> |
|||
|
|||
<ProFormSwitch name="enabled" label="是否启用" |
|||
fieldProps={ |
|||
{ defaultChecked: true } |
|||
} |
|||
/> |
|||
</ModalForm> |
|||
); |
|||
}; |
@ -0,0 +1,61 @@ |
|||
import React, { useRef } from 'react'; |
|||
import { Button, Form } from 'antd'; |
|||
import { |
|||
ModalForm, |
|||
ProFormText, |
|||
} from '@ant-design/pro-form'; |
|||
|
|||
export default (props) => { |
|||
const { title, triggerRender, editData = null, onFinish } = props; |
|||
const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } }; |
|||
const initialValues = {}; |
|||
const [form] = Form.useForm(); |
|||
const formRef = useRef(); |
|||
return ( |
|||
<ModalForm |
|||
formRef={formRef} |
|||
title={title || ''} |
|||
initialValues={initialValues} |
|||
trigger={ |
|||
triggerRender ? triggerRender : <Button type="primary" > |
|||
{title || ''} |
|||
</Button> |
|||
} |
|||
layout="horizontal" |
|||
grid={true} |
|||
{...formItemLayout} |
|||
modalProps={{ |
|||
destroyOnClose: true, |
|||
onCancel: () => { }, |
|||
}} |
|||
onFinish={async (values) => { |
|||
return onFinish && await onFinish({ ...values, msg: '重置密码' }, editData, '重置密码') |
|||
}} |
|||
width={500} |
|||
> |
|||
<ProFormText.Password |
|||
rules={[{ required: true, message: '请输入旧密码' }, |
|||
{ max: 255, message: '旧密码长度不能大于255个字符' }, |
|||
{ |
|||
pattern: /^[a-z0-9A-Z]{6,20}$/, message: '密码由6-20位字母或数字组成' |
|||
}, |
|||
]} |
|||
name="oldpassword" |
|||
label="旧密码" |
|||
/> |
|||
|
|||
<ProFormText.Password |
|||
rules={[{ required: true, message: '请输入新密码' }, |
|||
{ max: 255, message: '新密码长度不能大于255个字符' }, |
|||
{ |
|||
pattern: /^[a-z0-9A-Z]{6,20}$/, message: '密码由6-20位字母或数字组成' |
|||
}, |
|||
]} |
|||
name="password" |
|||
label="新密码" |
|||
/> |
|||
|
|||
|
|||
</ModalForm> |
|||
); |
|||
}; |
@ -0,0 +1,6 @@ |
|||
.step-footer { |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
margin-top: 20px; |
|||
width: 100%; |
|||
} |
@ -0,0 +1,26 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { Tabs, Card, Modal } from 'antd' |
|||
import AdapterStep from './adapterStep'; |
|||
import { STEP_CONFIG } from './steps/index' |
|||
function DataSourceModal(props) { |
|||
const { visible, editData, onFinish, onCancel, |
|||
type = 'postgre',//当前卡片的key (目前只有postgre,支持后续扩展)
|
|||
dataSourceFilter, |
|||
} = props; |
|||
const { StepThree } = STEP_CONFIG[type]; |
|||
// const onFinish = () => { }
|
|||
return <> |
|||
<Modal |
|||
title={editData ? '编辑采集任务' : "新建采集任务"} |
|||
onCancel={() => { onCancel() }} |
|||
open={visible} |
|||
footer={null} |
|||
width={1200} |
|||
destroyOnClose={true} |
|||
> |
|||
<StepThree next={onFinish} dataSourceFilter={dataSourceFilter} editData={editData} /> |
|||
</Modal> |
|||
</> |
|||
} |
|||
|
|||
export default DataSourceModal |
@ -0,0 +1,5 @@ |
|||
'use strict'; |
|||
|
|||
import DataSourceManagement from './member'; |
|||
|
|||
export { DataSourceManagement }; |
@ -0,0 +1,230 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { Spin, Popconfirm, Select, Row, Col, Button, Input, Table } from 'antd'; |
|||
import { connect } from 'react-redux'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import moment from 'moment'; |
|||
import MemberModal from '../components/memberModal'; |
|||
import ResetPasswordModal from '../components/resetPassword'; |
|||
import { useFsRequest, ApiTable } from '$utils'; |
|||
import './style.less'; |
|||
function Member(props) { |
|||
const { loading, clientHeight, actions, dispatch, member, user } = props; |
|||
const [pageSize, setPageSize] = useState(10); |
|||
const [currentPage, setCurrentPage] = useState(1); |
|||
const [searchValue, setSearchValue] = useState('') |
|||
const [visible, setVisible] = useState(false);//是否展示新增编辑模态框
|
|||
const [editData, setEditData] = useState(null);//模态框编辑数据
|
|||
const [refreshTree, setRefreshTree] = useState(1); |
|||
const [searchRole, setSearchRole] = useState() |
|||
const queryData = (search) => { |
|||
const query = { |
|||
limit: search ? 10 : pageSize || 10, |
|||
page: search ? 1 : currentPage || 1, |
|||
name: searchValue, |
|||
role: searchRole |
|||
} |
|||
|
|||
dispatch(actions.memberManagement.getUserList(query)); |
|||
} |
|||
const { data: treeData = [] } = useFsRequest({ |
|||
url: ApiTable.getResourceCatalog, |
|||
refreshDeps: [refreshTree] |
|||
}); |
|||
|
|||
useEffect(() => { |
|||
queryData(); |
|||
}, [pageSize, currentPage]); |
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '序号', |
|||
dataIndex: 'index', |
|||
render: (text, record, index) => { return index + 1 } |
|||
}, |
|||
{ |
|||
title: '姓名', |
|||
dataIndex: 'name', |
|||
}, |
|||
{ |
|||
title: '用户名', |
|||
dataIndex: 'username', |
|||
}, |
|||
{ |
|||
title: '角色', |
|||
dataIndex: 'role', |
|||
}, |
|||
{ |
|||
title: '状态', |
|||
dataIndex: 'enabled', |
|||
render: (text, record) => { |
|||
return <span style={{ color: record?.enabled ? '#87d068' : '#f50' }}>● {record?.enabled ? '正常' : '禁用'}</span> |
|||
} |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
width: 160, |
|||
key: 'option', |
|||
valueType: 'option', |
|||
render: (text, record) => { |
|||
const options = []; |
|||
options.push(<MemberModal |
|||
editData={record} |
|||
triggerRender={<a>编辑</a>} |
|||
title="编辑用户" |
|||
onFinish={onFinish} |
|||
key="editUser" |
|||
/>) |
|||
options.push( |
|||
<Popconfirm |
|||
key="del" |
|||
placement="top" |
|||
title={<><div>是否确认删除该用户?</div> |
|||
</>} |
|||
onConfirm={() => handleDelete(record.id)} |
|||
okText="是" |
|||
cancelText="否" |
|||
> |
|||
<a>删除</a> |
|||
</Popconfirm>) |
|||
user?.username == 'SuperAdmin' && options.push( |
|||
<Popconfirm |
|||
key="del" |
|||
placement="top" |
|||
title={<><div>是否确认重置该用户密码?</div> |
|||
</>} |
|||
onConfirm={() => { |
|||
dispatch(actions.memberManagement.modifyUser(record.id, { password: 'e10adc3949ba59abbe56e057f20f883e' }, '重置密码')) |
|||
}} |
|||
okText="是" |
|||
cancelText="否" |
|||
> |
|||
<a>重置密码</a> |
|||
</Popconfirm>) |
|||
|
|||
|
|||
return options; |
|||
|
|||
}, |
|||
}, |
|||
]; |
|||
|
|||
const handleDelete = (id) => { |
|||
dispatch(actions.memberManagement.deleteUser(id)).then(() => { |
|||
queryData(); |
|||
}); |
|||
}; |
|||
|
|||
const onFinish = async (values, editData) => { |
|||
if (editData) { |
|||
const dataToSave = { ...values } |
|||
return dispatch( |
|||
actions.memberManagement.modifyUser(editData.id, dataToSave, values?.msg || ''), |
|||
).then((res) => { |
|||
if (res.success) { |
|||
queryData(); |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
return dispatch(actions.memberManagement.addUser({ |
|||
...values, |
|||
})).then(res => { |
|||
if (res.success) { |
|||
queryData(); |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
return <Spin spinning={loading}> |
|||
<Row className='protable-title'> |
|||
<Col span={12}> |
|||
<MemberModal |
|||
triggerRender={<Button type='primary'>新建</Button>} |
|||
title="新建用户" |
|||
onFinish={onFinish} |
|||
key="addModel" |
|||
/> |
|||
</Col> |
|||
<Col span={12} style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}> |
|||
<span>用户姓名: </span> <Input |
|||
value={searchValue} onChange={e => { setSearchValue(e.target.value) }} |
|||
style={{ width: 220, marginRight: 15 }} placeholder="请输入" /> |
|||
|
|||
<span>角色: </span> <Select |
|||
allowClear |
|||
value={searchRole} onChange={e => { setSearchRole(e) }} |
|||
style={{ width: 220, marginRight: 15 }} placeholder="请选择" > |
|||
<Select.Option value={'系统管理员'}>系统管理员</Select.Option> |
|||
<Select.Option value={'数据消费者'}>数据消费者</Select.Option> |
|||
</Select> |
|||
|
|||
<Button onClick={() => { |
|||
setCurrentPage(1) |
|||
setPageSize(10) |
|||
queryData(true) |
|||
}} type='primary'>查询</Button></Col> |
|||
|
|||
</Row> |
|||
<ProTable |
|||
columns={columns} |
|||
dateFormatter="string" |
|||
search={false} |
|||
scroll={ |
|||
{ |
|||
scrollToFirstRowOnChange: true, |
|||
y: clientHeight - 260 |
|||
} |
|||
} |
|||
pagination={{ |
|||
size: 'large', |
|||
total: member?.count, |
|||
showSizeChanger: true, |
|||
showQuickJumper: true, |
|||
current: currentPage, |
|||
pageSize: pageSize || 10, |
|||
defaultPageSize: 10, |
|||
pageSizeOptions: [10, 20, 50], |
|||
showTotal: (total) => { |
|||
return <span style={{ fontSize: 15 }}>{`共${Math.ceil(total / pageSize)}页,${total}项`}</span> |
|||
}, |
|||
onShowSizeChange: (currentPage, pageSize) => { |
|||
setCurrentPage(currentPage); |
|||
setPageSize(pageSize); |
|||
|
|||
}, |
|||
onChange: (page, pageSize) => { |
|||
setCurrentPage(page); |
|||
setPageSize(pageSize); |
|||
|
|||
} |
|||
}} |
|||
dataSource={member?.rows || []} |
|||
options={false} |
|||
/> |
|||
</Spin> |
|||
|
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { |
|||
auth, global, datasources, member |
|||
} = state; |
|||
return { |
|||
loading: datasources.isRequesting, |
|||
clientHeight: global.clientHeight, |
|||
actions: global.actions, |
|||
member: member?.data || {}, |
|||
user: auth.user |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Member); |
|||
|
|||
|
|||
|
@ -0,0 +1,5 @@ |
|||
.protable-title { |
|||
margin-bottom: 16px; |
|||
padding-left: 24px; |
|||
padding-right: 24px; |
|||
} |
@ -0,0 +1,15 @@ |
|||
'use strict'; |
|||
|
|||
import reducers from './reducers'; |
|||
import routes from './routes'; |
|||
import actions from './actions'; |
|||
import { getNavItem } from './nav-item'; |
|||
|
|||
export default { |
|||
key: 'memberManagement', |
|||
name: '用户管理', |
|||
reducers: reducers, |
|||
routes: routes, |
|||
actions: actions, |
|||
getNavItem: getNavItem |
|||
}; |
@ -0,0 +1,17 @@ |
|||
import React from 'react'; |
|||
import { Link } from 'react-router-dom'; |
|||
import { Menu } from 'antd'; |
|||
import { BarChartOutlined } from '@ant-design/icons'; |
|||
const SubMenu = Menu.SubMenu; |
|||
|
|||
export function getNavItem(user) { |
|||
|
|||
return ( |
|||
user?.role == '系统管理员' && <SubMenu key="memberManagement" icon={<BarChartOutlined />} title='用户管理'> |
|||
<Menu.Item key="auth"> |
|||
<Link to="/memberManagement/auth">用户权限</Link> |
|||
</Menu.Item> |
|||
</ SubMenu > |
|||
) |
|||
|
|||
} |
@ -0,0 +1,5 @@ |
|||
'use strict'; |
|||
|
|||
export default { |
|||
|
|||
} |
@ -0,0 +1,17 @@ |
|||
'use strict'; |
|||
import { Adapter, DataSourceManagement, AcquisitionTask, AcquisitionLog, AdapterDetail } from './containers'; |
|||
export default [{ |
|||
type: 'inner', |
|||
route: { |
|||
path: '/memberManagement', |
|||
key: 'memberManagement', |
|||
breadcrumb: '用户管理', |
|||
// 不设置 component 则面包屑禁止跳转
|
|||
childRoutes: [{ |
|||
path: '/auth', |
|||
key: 'auth', |
|||
component: DataSourceManagement, |
|||
breadcrumb: '权限管理' |
|||
}] |
|||
} |
|||
}]; |
Loading…
Reference in new issue