| | |
| | | component: './setting/role', |
| | | access: '/system_setting/role_management', |
| | | }, |
| | | { |
| | | name: '人员管理', |
| | | path: '/setting/user', |
| | | component: './setting/user', |
| | | // access: '/system_setting/user_management', |
| | | } |
| | | ], |
| | | }, |
| | | { |
New file |
| | |
| | | import { Form, Input, Modal, Tree, Button, Spin } from 'antd'; |
| | | import { forwardRef, useImperativeHandle, useState } from 'react'; |
| | | import { useEffect } from 'react'; |
| | | import { getTree, getAddTree } from '../service'; |
| | | const formItemLayout = { |
| | | labelCol: { span: 6 }, |
| | | wrapperCol: { span: 18 }, |
| | | }; |
| | | |
| | | |
| | | const AddAndEdit = ({ visible, onSave, onUpdate, onCancel }, ref) => { |
| | | const [form] = Form.useForm(); |
| | | const [data, setData] = useState({}) |
| | | const [treeData, setTreeData] = useState([]);//权限树 |
| | | const [treeSeletKeys, setTreeSeletKeys] = useState([]); //勾选权限 |
| | | const [detailType, setDetailType] = useState(false);//是否详情 |
| | | const [spinning, setSpinning] = useState(false); |
| | | |
| | | useEffect(() => { |
| | | // 获取权限树 |
| | | getAddTree().then(res => { |
| | | setTreeData(res.data) |
| | | }) |
| | | }, []) |
| | | |
| | | useImperativeHandle(ref, () => { |
| | | return { |
| | | refreshData: (data, type) => { |
| | | setDetailType(type || false) |
| | | if (data.id) { |
| | | // 获取角色的权限树 |
| | | getTree(data.id).then(res => { |
| | | setTreeSeletKeys(res.data.systemMenuIds || []); |
| | | }) |
| | | } |
| | | setData(data) |
| | | form.setFieldsValue(data); |
| | | }, |
| | | clean: () => { |
| | | setSpinning(false) |
| | | }, |
| | | }; |
| | | }); |
| | | |
| | | // 保存 |
| | | const okHandle = () => { |
| | | form.validateFields().then((values) => { |
| | | setSpinning(true) |
| | | values.menuIds = treeSeletKeys |
| | | delete values.tree |
| | | if (data.id) { |
| | | values.id = data.id |
| | | onUpdate(values) |
| | | } else { |
| | | onSave(values); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 选中树 |
| | | const onCheck = (e, row) => { |
| | | let seletKeys = e.checked; |
| | | treeData.find(item => { |
| | | if (item.children) { |
| | | let arr1 = item.children.find((item1) => {//循环子路由 |
| | | if (item1.children) { |
| | | let arr2 = item1.children.find((item2) => {//循环子路由下按钮 |
| | | return item2.id == row.node.id; |
| | | }); |
| | | if (row.checked) { |
| | | if (arr2 && !seletKeys.includes(item1.id)) { |
| | | seletKeys.push(item1.id); |
| | | } |
| | | if (arr2 && !seletKeys.includes(item.id)) { |
| | | seletKeys.push(item.id); |
| | | } |
| | | } else { |
| | | let isCheck = item1.children.find((item2) => seletKeys.includes(item2.id)); |
| | | if (!isCheck) { |
| | | let arr = seletKeys.filter((it) => it != item1.id); |
| | | seletKeys = arr; |
| | | } |
| | | } |
| | | } |
| | | return item1.id == row.node.id; |
| | | }); |
| | | if (row.checked) { |
| | | if (arr1 && !seletKeys.includes(item.id)) { |
| | | seletKeys.push(item.id); |
| | | } |
| | | } else { |
| | | let isCheck = item.children.find((item1) => seletKeys.includes(item1.id)); |
| | | if (!isCheck) { |
| | | let arr = seletKeys.filter((it) => it != item.id); |
| | | seletKeys = arr; |
| | | } |
| | | } |
| | | } |
| | | return item.id == row.node.id; |
| | | }); |
| | | if (row.node.children.length != 0) { |
| | | row.node.children.map((item) => { |
| | | if (row.checked) { |
| | | if (!seletKeys.includes(item.id)) { |
| | | seletKeys.push(item.id); |
| | | } |
| | | } else { |
| | | seletKeys = seletKeys.filter((item1) => item1 != item.id); |
| | | } |
| | | if (item.children.length != 0) { |
| | | item.children.map((item1) => { |
| | | if (row.checked) { |
| | | if (!seletKeys.includes(item1.id)) { |
| | | seletKeys.push(item1.id); |
| | | } |
| | | } else { |
| | | seletKeys = seletKeys.filter((item2) => item2 != item1.id); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | setTreeSeletKeys(seletKeys); |
| | | }; |
| | | |
| | | return ( |
| | | <Modal |
| | | getContainer={false} |
| | | width="20%" |
| | | destroyOnClose |
| | | title={detailType ? '角色详情' : data.id ? '编辑角色' : '添加角色'} |
| | | open={visible} |
| | | onCancel={() => onCancel(false)} |
| | | afterClose={() => { |
| | | form.resetFields() |
| | | setTreeSeletKeys([]) |
| | | }} |
| | | footer={ |
| | | !detailType ? |
| | | [ |
| | | <Button key="back" onClick={() => onCancel(false)}>取消</Button>, |
| | | <Button key="submit" type="primary" onClick={okHandle}> |
| | | 确定 |
| | | </Button> |
| | | ] |
| | | : |
| | | <Button key="back" onClick={() => onCancel(false)}>关闭</Button> |
| | | } |
| | | > |
| | | <Form layout="horizontal" {...formItemLayout} form={form} scrollToFirstError> |
| | | <Form.Item |
| | | name="name" |
| | | label="角色名称" |
| | | rules={[{ required: true, message: '请输入角色名称' }]} |
| | | > |
| | | <Input disabled={detailType} placeholder='请输入角色名称' /> |
| | | </Form.Item> |
| | | <Form.Item |
| | | name="tree" |
| | | label="角色权限" |
| | | rules={[{ |
| | | required: true, |
| | | validator: (rule, value) => { |
| | | return new Promise((resolve, reject) => { |
| | | if (value) { |
| | | resolve(''); |
| | | } else { |
| | | if (treeSeletKeys.length === 0) { |
| | | reject(new Error('请选择角色权限')); |
| | | } |
| | | resolve(''); |
| | | } |
| | | }) |
| | | } |
| | | }]}> |
| | | <Tree |
| | | checkable |
| | | checkStrictly |
| | | checkedKeys={treeSeletKeys} |
| | | treeData={treeData} |
| | | disabled={detailType} |
| | | fieldNames={{ title: 'name', key: 'id' }} |
| | | onCheck={onCheck} |
| | | /> |
| | | </Form.Item> |
| | | </Form> |
| | | <Spin spinning={spinning} fullscreen /> |
| | | </Modal > |
| | | ); |
| | | }; |
| | | |
| | | export default forwardRef(AddAndEdit); |
New file |
| | |
| | | import { buildProTableDataSource, sendRequest, showDelConfirm } from '@/utils/antdUtils'; |
| | | import { PageContainer, ProFormText, ProTable, QueryFilter } from '@ant-design/pro-components'; |
| | | import { Button, Col, Row, Menu ,Space } from 'antd'; |
| | | import { useRef, useState } from 'react'; |
| | | import { Access, useAccess } from 'umi'; |
| | | import AddAndEdit from './components/addAndEdit'; |
| | | import { AppstoreOutlined, MailOutlined, SettingOutlined } from '@ant-design/icons'; |
| | | import { add, del, edit, getList } from './service'; |
| | | |
| | | const Role = () => { |
| | | const actionRef = useRef(); |
| | | const addViewRef = useRef(); |
| | | const [modalVisible, handleModalVisibles] = useState(false); |
| | | const access = useAccess(); |
| | | const items = [ |
| | | { |
| | | key: '1', |
| | | icon: <MailOutlined />, |
| | | label: 'Navigation One', |
| | | children: [ |
| | | { |
| | | key: '11', |
| | | label: 'Option 1', |
| | | }, |
| | | { |
| | | key: '12', |
| | | label: 'Option 2', |
| | | }, |
| | | { |
| | | key: '13', |
| | | label: 'Option 3', |
| | | }, |
| | | { |
| | | key: '14', |
| | | label: 'Option 4', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | key: '2', |
| | | icon: <AppstoreOutlined />, |
| | | label: 'Navigation Two', |
| | | children: [ |
| | | { |
| | | key: '21', |
| | | label: 'Option 1', |
| | | }, |
| | | { |
| | | key: '22', |
| | | label: 'Option 2', |
| | | }, |
| | | { |
| | | key: '23', |
| | | label: 'Submenu', |
| | | children: [ |
| | | { |
| | | key: '231', |
| | | label: 'Option 1', |
| | | }, |
| | | { |
| | | key: '232', |
| | | label: 'Option 2', |
| | | }, |
| | | { |
| | | key: '233', |
| | | label: 'Option 3', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | key: '24', |
| | | label: 'Submenu 2', |
| | | children: [ |
| | | { |
| | | key: '241', |
| | | label: 'Option 1', |
| | | }, |
| | | { |
| | | key: '242', |
| | | label: 'Option 2', |
| | | }, |
| | | { |
| | | key: '243', |
| | | label: 'Option 3', |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | key: '3', |
| | | icon: <SettingOutlined />, |
| | | label: 'Navigation Three', |
| | | children: [ |
| | | { |
| | | key: '31', |
| | | label: 'Option 1', |
| | | }, |
| | | { |
| | | key: '32', |
| | | label: 'Option 2', |
| | | }, |
| | | { |
| | | key: '33', |
| | | label: 'Option 3', |
| | | }, |
| | | { |
| | | key: '34', |
| | | label: 'Option 4', |
| | | }, |
| | | ], |
| | | }, |
| | | ]; |
| | | const columns = [ |
| | | { |
| | | title: '角色名称', |
| | | dataIndex: 'name', |
| | | }, |
| | | { |
| | | title: '操作', |
| | | hideInSearch: true, |
| | | render: (text, record) => { |
| | | return ( |
| | | <Space> |
| | | {record.roleId != 1 && ( |
| | | <Access accessible={access['/system_setting/role_management/edit']}> |
| | | <Button |
| | | type="link" |
| | | onClick={() => { |
| | | addViewRef.current.refreshData(record); |
| | | handleModalVisibles(true); |
| | | }} |
| | | > |
| | | 编辑 |
| | | </Button> |
| | | </Access> |
| | | )} |
| | | {record.roleId != 1 && ( |
| | | <Access accessible={access['/system_setting/role_management/del']}> |
| | | <Button |
| | | type="link" |
| | | onClick={() => { |
| | | showDelConfirm(async () => { |
| | | let status = await sendRequest(del, record.id); |
| | | if (status) { |
| | | actionRef.current.reload(); |
| | | } |
| | | }, '确认删除所选信息吗?'); |
| | | }} |
| | | > |
| | | 删除 |
| | | </Button> |
| | | </Access> |
| | | )} |
| | | <Access accessible={access['/system_setting/role_management/detail'] || false}> |
| | | <Button |
| | | type="link" |
| | | onClick={() => { |
| | | addViewRef.current.refreshData(record, true); |
| | | handleModalVisibles(true); |
| | | }} |
| | | > |
| | | 查看详情 |
| | | </Button> |
| | | </Access> |
| | | </Space> |
| | | ); |
| | | }, |
| | | }, |
| | | ]; |
| | | |
| | | return ( |
| | | <PageContainer |
| | | header={{ |
| | | breadcrumb: {}, |
| | | }} |
| | | > |
| | | <div style={{ background: '#fff' }}> |
| | | <QueryFilter> |
| | | <ProFormText name="name" label="单位名称" /> |
| | | </QueryFilter> |
| | | </div> |
| | | <Row style={{ marginTop: 20, background: '#fff' }}> |
| | | <Col span={4}> |
| | | <Menu |
| | | mode="inline" |
| | | defaultSelectedKeys={['231']} |
| | | style={{ |
| | | // width: 256, |
| | | }} |
| | | items={items} |
| | | /> |
| | | </Col> |
| | | <Col span={20} style={{ minHeight: 650 }}> |
| | | <ProTable |
| | | rowKey="id" |
| | | actionRef={actionRef} |
| | | columns={columns} |
| | | pagination={{ |
| | | showSizeChanger: true, |
| | | showQuickJumper: true, |
| | | defaultPageSize: 10, |
| | | }} |
| | | request={(params) => buildProTableDataSource(getList, params)} |
| | | toolBarRender={(action, selectRows) => [ |
| | | <Access accessible={access['/system_setting/role_management/add']}> |
| | | <Space> |
| | | <Button |
| | | type="primary" |
| | | onClick={() => { |
| | | addViewRef.current.refreshData({}); |
| | | handleModalVisibles(true); |
| | | }} |
| | | > |
| | | 添加 |
| | | </Button> |
| | | </Space> |
| | | </Access>, |
| | | ]} |
| | | /> |
| | | </Col> |
| | | </Row> |
| | | |
| | | <AddAndEdit |
| | | ref={addViewRef} |
| | | visible={modalVisible} |
| | | onSave={async (fileds) => { |
| | | let success = await sendRequest(add, fileds); |
| | | if (success) { |
| | | handleModalVisibles(false); |
| | | actionRef.current.reload(); |
| | | } |
| | | addViewRef.current.clean(); |
| | | }} |
| | | onUpdate={async (fileds) => { |
| | | let success = await sendRequest(edit, fileds); |
| | | if (success) { |
| | | handleModalVisibles(false); |
| | | actionRef.current.reload(); |
| | | } |
| | | addViewRef.current.clean(); |
| | | }} |
| | | onCancel={() => handleModalVisibles(false)} |
| | | /> |
| | | </PageContainer> |
| | | ); |
| | | }; |
| | | |
| | | export default Role; |
New file |
| | |
| | | import { request } from '@umijs/max'; |
| | | |
| | | // 列表 |
| | | export const getList = async (params) => { |
| | | return request(`/api/huacheng-sangeshenbian/systemRole/list`, { |
| | | method: 'GET', |
| | | params |
| | | }); |
| | | } |
| | | |
| | | // 编辑获取角色权限树 |
| | | export const getTree = async (id) => { |
| | | return request(`/api/huacheng-sangeshenbian/systemRole/getSystemRoleInfo/${id}`, { |
| | | method: 'GET', |
| | | }); |
| | | } |
| | | |
| | | // 新增获取权限树 |
| | | export const getAddTree = async (id) => { |
| | | return request(`/api/huacheng-sangeshenbian/systemMenu/getSystemMenuList`, { |
| | | method: 'GET', |
| | | }); |
| | | } |
| | | |
| | | // 新增 |
| | | export const add = async (data) => { |
| | | return request('/api/huacheng-sangeshenbian/systemRole/add', { |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // 编辑 |
| | | export const edit = async (data) => { |
| | | return request('/api/huacheng-sangeshenbian/systemRole/edit', { |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // 删除 |
| | | export const del = async (id) => { |
| | | return request(`/api/huacheng-sangeshenbian/systemRole/delete/${id}`, { |
| | | method: 'DELETE', |
| | | }); |
| | | } |
| | | |