zhouna 3 лет назад
Родитель
Сommit
e913844096

+ 1 - 0
src/api/index.js

@@ -45,6 +45,7 @@ axios.interceptors.request.use(function (req) {
     if (tokenStr) {
         req.headers.Authorization = `Bearer ${tokenStr}`;
         req.headers.hospitalId=1;
+        req.headers.softwareId=1;
         return req;
     } else {
         return req;

+ 9 - 0
src/api/request.js

@@ -12,6 +12,15 @@ const request = {
     resetPassword:'/security-center/hospitalManage/resetPassword',  //重置密码
     //角色管理相关接口
     getUserMenuResourceTree:'/security-center/roleManage/getUserMenuResourceTree',      //获取菜单权限树
+    addRole:'/security-center/roleManage/addRole',      //添加角色
+    deleteRole:'/security-center/roleManage/deleteRole',    //删除角色
+    disableRole:'/security-center/roleManage/disableRole',      //启用禁用
+    getRolePage:'/security-center/roleManage/getRolePage',      //角色列表
+    getRoleById:'/security-center/roleManage/getRoleById',      //角色详情
+    getCreateRoles:'/security-center/roleManage/getCreateRoles',    //当前登录用户管理的角色列表
+    getUserShowMemuTree:'/security-center/roleManage/getUserShowMemuTree',      //菜单列表
+    updateRole:'/security-center/roleManage/updateRole',        //修改角色
+
 
     //用户管理相关接口
     getHospitalTree:"/security-center/userManage/getHospitalTree",

+ 0 - 1
src/components/OrgManager/AddSubOrg.js

@@ -228,7 +228,6 @@ function StepContent(props){
                 hidden={current!==0}
                 rules={[{ required: true }]}>
                 <Select placeholder='请选择类型'>
-                    <Option value="">全部</Option>
                     {typeList.map((item,i)=>{
                         return (
                             <Option value={item.name} key={i}>{item.val}</Option>

+ 0 - 294
src/components/OrgManager/OrgManager.js

@@ -1,294 +0,0 @@
-import {useEffect,useState} from 'react';
-/*import { useDispatch,useSelector } from 'react-redux'*/
-import { Table,Modal, message, Menu, Breadcrumb, Dropdown, Space, Form, Input, Button, Row, Col, Select } from 'antd';
-import { DownOutlined,PlusOutlined } from '@ant-design/icons';
-import AddSubOrg from './AddSubOrg';
-import './index.less';
-import apiObj from '@api/index';
-import OrgContext from './org-context';
-
-const {post,api,xPost} = apiObj;
-const { Option } = Select;
-function OrgManager(){
-    useEffect(() => {
-        getFilterList();
-        getTableData();
-    },[]);
-
-    const [dataSource, setDataSource] = useState([]);
-    const [typeList,setTypeList] = useState([]);
-    const [visible,setVisible] = useState(false);
-    const [addVisible,setAddVisible] = useState(false);
-    const [confirmLoading, setConfirmLoading] = useState(false);
-    //弹窗类型:1删除 2有子组织、用户删除 3禁用 4有子组织、用户禁用 5重置密码
-    const [modalType,setModalType] = useState(1);
-    const [modalTitle,setModalTitle] = useState(1);
-    const [operId,setOperId] = useState('');
-    const [orgId,setOrgId] = useState('');
-    const [orgName,setOrgName] = useState('');
-
-    const tipText={
-        1:'确定要删除该组织?',
-        2:'当前组织内可能包含子组织或其相关用户,删除后所包含信息将一并被删除',
-        3:'确定要禁用该组织?',
-        4:'当前组织内可能包含子组织或其相关用户,禁用后所包含信息将一并被禁用',
-        5:'确定要重置该组织密码?',
-    };
-
-    //获取筛选下拉数据
-    function getFilterList(){
-        post(api.getManagerBoxInfo).then((res)=>{
-            if(res.data.code===200){
-                const data = res.data.data;
-                setTypeList(data[43]);
-            }
-        })
-    }
-    //获取表格数据
-    function getTableData(param={}){
-        post(api.getHospitalListInfo,param).then((res)=>{
-            if(res.data.code===200){
-                const data = res.data.data;
-                setOrgId(data[0]?data[0].hospitalId:'');
-                setOrgName(data[0]?data[0].hospitalName:'')
-                setDataSource(data);
-            }
-
-        })
-    }
-    //启用/禁用
-    function enable(flag,id) {
-        const param = {HospitalId:id||operId,status:flag};
-        xPost(api.disableHospital,param).then((res)=>{
-            if(res.data.code===200){
-                getTableData();
-                setVisible(false);
-                message.success((flag?'启用':'禁用')+"成功");
-            }else{
-                message.warning(res.data.msg||'操作失败');
-            }
-        }).catch(()=>{
-            message.error("接口出错");
-        });
-    }
-    //重置密码
-    function onResetPsd(){
-        const param = {HospitalId:operId};
-        xPost(api.resetPassword,param).then((res)=>{
-            if(res.data.code===200){
-                getTableData();
-                setVisible(false)
-                message.success("重置成功");
-            }else{
-                message.warning(res.data.msg||'操作失败');
-            }
-        }).catch(()=>{
-            message.error("接口出错");
-        });
-    }
-    //删除
-    function onDelete(){
-        const param = {HospitalId:operId};
-        xPost(api.deleteHospital,param).then((res)=>{
-            if(res.data.code===200){
-                getTableData();
-                setVisible(false);
-                message.success("删除成功");
-            }else{
-                message.warning(res.data.msg||'操作失败');
-            }
-        }).catch(()=>{
-            message.error("接口出错");
-        });
-    }
-    //显示弹窗
-    function showModal(type,id){
-        setModalType(type);
-        setOperId(id);
-        setVisible(true);
-    }
-    //弹窗确认事件
-    function handleOk(){
-        if("1,2".indexOf(modalType)>-1){
-            onDelete();
-        }else if("3,4".indexOf(modalType)>-1){
-            enable(0);
-        }else if(modalType===5){
-            onResetPsd();
-        }
-
-    }
-    //弹窗取消
-    function handleCancel(){
-        setVisible(false);
-        setAddVisible(false);
-    }
-    //新增子组织弹窗
-    function showAddModal(title){
-        setModalTitle(title);
-        setAddVisible(true);
-    }
-    //保存
-    function addSubOrg(formData){
-        console.log('保存参数:',formData);
-        const param = formData;
-        post(api.addHospital,param).then((res)=>{
-            if(res.data.code===200){
-                getTableData();
-                setAddVisible(false);
-                message.success("添加成功");
-            }else{
-                message.warning(res.data.msg||'操作失败');
-            }
-        }).catch(()=>{
-            message.error("接口出错");
-        });
-    }
-    //表格渲染
-    function RenderTable(){
-        const columns = [
-            { title: '组织机构层级', dataIndex: 'hospitalName', key: 'hospitalName' },
-            { title: '类型',  key: 'type',render:(row)=>{
-                    if(row.children){
-                        return '-'
-                    }else{
-                        return row.type;
-                    }
-                } },
-            { title: '状态',  key: 'status',render:(row)=>{
-                    if(row.children){
-                        return '-'
-                    }else{
-                        return row.status;
-                    }
-                } },
-            { title: '创建时间', dataIndex: 'gmtCreate', key: 'gmtCreate' },
-            { title: '操作', key: 'operation', render: (row) => {
-                    //console.log(21,row)
-                    if(row.children){
-                        return '-'
-                    }
-                    const menu = (
-                        <Menu>
-                            <Menu.Item key="0" onClick={()=>showModal(5,row.hospitalId)}>重置密码</Menu.Item>
-                            <Menu.Item key="1" onClick={()=>showModal((row.hasUserFlag||row.hasHospitalFlag?2:1),row.hospitalId)}>删除</Menu.Item>
-                        </Menu>
-                    );
-                    return (<Space size="middle">
-                        <a>修改</a>
-                        {row.status==='1'?(<a onClick={()=>showModal(row.hasUserFlag||row.hasHospitalFlag?4:3,row.hospitalId)}>禁用</a>):(<a onClick={()=>enable(1,row.hospitalId)}>启用</a>)}
-                        <Dropdown overlay={menu} trigger={['click']}>
-                            <a className="ant-dropdown-link">
-                                更多 <DownOutlined />
-                            </a>
-                        </Dropdown>
-                    </Space>) }},
-        ];
-        return (
-            <Table
-                pagination={false}
-                className="components-table-demo-nested"
-                rowKey={record => record.hospitalId}
-                expandable={{defaultExpandAllRows:true}}
-                columns={columns}
-                dataSource={dataSource}
-            />
-        )
-    }
-    //筛选项渲染
-    const [form] = Form.useForm();
-    const onFinish = (values: any) => {
-        getTableData(values);
-        console.log('筛选项:',values);
-    };
-    const onReset = () => {
-        form.resetFields();
-        getTableData();
-    };
-    return (
-        <div className='container'>
-            <div className="filter-box">
-                <Form form={form} name="control-hooks" onFinish={onFinish}>
-                    <Row gutter={24}>
-                        <Col span={5} key={0}>
-                            <Form.Item name="hospitalName" label="组织名称">
-                                <Input placeholder='组织名称'/>
-                            </Form.Item>
-                        </Col>
-                        <Col span={5} key={1}>
-
-                            <Form.Item name="type" label="类型">
-                                <Select
-                                    allowClear
-                                >
-                                    <Option value="">全部</Option>
-                                    {typeList.map((item)=>{
-                                        return (
-                                            <Option value={item.name}  key={item.name}>{item.val}</Option>
-                                        )
-                                    })}
-                                </Select>
-                            </Form.Item>
-                        </Col>
-                        <Col span={5} key={2}>
-                            <Form.Item name="status" label="当前状态">
-                                <Select
-                                    allowClear
-                                >
-                                    <Option value="">全部</Option>
-                                    <Option value="1">启用</Option>
-                                    <Option value="0">禁用</Option>
-                                </Select>
-                            </Form.Item>
-                        </Col>
-                        <Col span={9} key={3}>
-                            <Form.Item>
-                                <Button type="primary" htmlType="submit">
-                                    查询
-                                </Button>
-                                <Button htmlType="button" onClick={onReset}>
-                                    重置
-                                </Button>
-                            </Form.Item>
-                        </Col>
-                    </Row>
-                </Form>
-            </div>
-            <div className="table">
-                <div className="table-header">
-                    <Breadcrumb>
-                        <Breadcrumb.Item>组织管理</Breadcrumb.Item>
-                    </Breadcrumb>
-                    <Button type="primary" icon={<PlusOutlined />} onClick={()=> showAddModal('新增子组织')}>新增子组织</Button>
-                </div>
-                <RenderTable />
-            </div>
-            <Modal
-                title="提示"
-                okText='确定'
-                cancelText='取消'
-                width={400}
-                visible={visible}
-                onOk={handleOk}
-                confirmLoading={confirmLoading}
-                onCancel={handleCancel}
-            >
-                <p>{tipText[modalType]}</p>
-            </Modal>
-            <Modal
-                title={modalTitle}
-                footer={null}
-                width={690}
-                visible={addVisible}
-                confirmLoading={confirmLoading}
-                onCancel={handleCancel}
-            >
-                <OrgContext.Provider value={{orgId,orgName,typeList,save:addSubOrg}}>
-                    <AddSubOrg />
-                </OrgContext.Provider>
-            </Modal>
-        </div>
-    )
-}
-
-export default OrgManager;

+ 36 - 18
src/components/OrgManager/index.js

@@ -15,17 +15,18 @@ function OrgManager(){
         getTableData();
     },[]);
 
-    const [dataSource, setDataSource] = useState([]);
-    const [typeList,setTypeList] = useState([]);
-    const [visible,setVisible] = useState(false);
-    const [addVisible,setAddVisible] = useState(false);
+    const [dataSource, setDataSource] = useState([]);   //列表数据
+    const [orgDetail, setOrgDetail] = useState([]);   //组织详情数据
+    const [typeList,setTypeList] = useState([]);        //组织类型
+    const [statusList,setStatusList] = useState([]);        //状态
+    const [visible,setVisible] = useState(false);   //删除禁用确认弹窗显示
+    const [addVisible,setAddVisible] = useState(false);         //新增页面显示
     const [confirmLoading, setConfirmLoading] = useState(false);
     //弹窗类型:1删除 2有子组织、用户删除 3禁用 4有子组织、用户禁用 5重置密码
     const [modalType,setModalType] = useState(1);
-    const [modalTitle,setModalTitle] = useState(1);
-    const [operId,setOperId] = useState('');
-    const [orgId,setOrgId] = useState('');
-    const [orgName,setOrgName] = useState('');
+    const [operId,setOperId] = useState('');    //当前操作的组织id
+    const [orgId,setOrgId] = useState('');      //上级组织id
+    const [orgName,setOrgName] = useState('');      //上级组织名称,新增修改用
 
     const tipText={
         1:'确定要删除该组织?',
@@ -41,6 +42,7 @@ function OrgManager(){
             if(res.data.code===200){
                 const data = res.data.data;
                 setTypeList(data[43]);
+                setStatusList(data[47]);
             }
         })
     }
@@ -124,8 +126,22 @@ function OrgManager(){
         setAddVisible(false);
     }
     //新增子组织弹窗
-    function showAddModal(title){
-        setModalTitle(title);
+    function showAddOrg(){
+        setAddVisible(true);
+    }
+    function getOrgDetail(id,type){
+        xPost(api.getHospitalById,{HospitalId:id,type}).then((res)=>{
+            if(res.data.code===200){
+                console.log(res.data.data)
+                //setOrgDetail(res.data.data);
+            }else{
+                message.warning(res.data.msg||'获取详情失败')
+            }
+        });
+    }
+    //修改子组织
+    function editSubOrg(id,type){
+        getOrgDetail(id,type);
         setAddVisible(true);
     }
     //保存
@@ -155,20 +171,20 @@ function OrgManager(){
                     if(row.children){
                         return '-'
                     }else{
-                        return row.type;
+                        return row.typeName;
                     }
                 } },
             { title: '状态',  key: 'status',render:(row)=>{
                     if(row.children){
                         return '-'
                     }else{
-                        return row.status;
+                        return row.statusName;
                     }
                 } },
             { title: '创建时间', dataIndex: 'gmtCreate', key: 'gmtCreate' },
             { title: '操作', key: 'operation', render: (row) => {
                     //console.log(21,row)
-                    if(row.children){
+                    if(row.rootFlag){
                         return '-'
                     }
                     const menu = (
@@ -178,7 +194,7 @@ function OrgManager(){
                         </Menu>
                     );
                     return (<Space size="middle">
-                        <a>修改</a>
+                        <a onClick={()=>editSubOrg(row.hospitalId,row.type)}>修改</a>
                         {row.status==='1'?(<a onClick={()=>showModal(row.hasUserFlag||row.hasHospitalFlag?4:3,row.hospitalId)}>禁用</a>):(<a onClick={()=>enable(1,row.hospitalId)}>启用</a>)}
                         <Dropdown overlay={menu} trigger={['click']}>
                             <a className="ant-dropdown-link">
@@ -244,9 +260,11 @@ function OrgManager(){
                                 <Select
                                     allowClear
                                 >
-                                    <Option value="">全部</Option>
-                                    <Option value="1">启用</Option>
-                                    <Option value="0">禁用</Option>
+                                    {statusList.map((item)=>{
+                                        return (
+                                            <Option value={item.name}  key={item.name}>{item.val}</Option>
+                                        )
+                                    })}
                                 </Select>
                             </Form.Item>
                         </Col>
@@ -268,7 +286,7 @@ function OrgManager(){
                     <Breadcrumb>
                         <Breadcrumb.Item>组织管理</Breadcrumb.Item>
                     </Breadcrumb>
-                    <Button type="primary" icon={<PlusOutlined />} onClick={()=> showAddModal('新增子组织')}>新增子组织</Button>
+                    <Button type="primary" icon={<PlusOutlined />} onClick={()=> showAddOrg()}>新增子组织</Button>
                 </div>
                 <RenderTable />
             </div>

+ 217 - 0
src/components/RoleManager/AddRole.js

@@ -0,0 +1,217 @@
+import {useEffect,useState,useContext} from 'react';
+import { Form, Input, Checkbox, Button, Select,Tabs ,InputNumber,Space,Switch,Breadcrumb  } from 'antd';
+import MenuTree  from './MenuTree';
+import './index.less';
+import RoleContext from './role-context';
+import apiObj from '@api/index';
+import backIcon from "@images/back.png";
+
+const {post,api,xPost} = apiObj;
+
+const { TabPane } = Tabs;
+const { Option } = Select;
+function AddRole(props){
+    const { back } = props;
+
+    return (
+        <>
+            <Breadcrumb separator="">
+                <Breadcrumb.Item><img className='back-icon' src={backIcon} onClick={back} alt="返回上一页"/></Breadcrumb.Item>
+                <Breadcrumb.Item>组织管理</Breadcrumb.Item>
+                <Breadcrumb.Separator />
+                <Breadcrumb.Item>新增角色</Breadcrumb.Item>
+            </Breadcrumb>
+            <div className="add-container">
+                <ContentForm></ContentForm>
+            </div>
+        </>
+    )
+}
+
+function ContentForm(props){
+    const [form] = Form.useForm();
+    const [treeDatas, setTreeDatas] = useState([]);
+    const [tabDatas, setTabDatas] = useState([]);
+    const [activeTab, setActiveTab] = useState('');
+    const [sysCheckeds, setSysCheckeds] = useState([]);
+    const {save}  = useContext(RoleContext);
+    const initialValues={
+        status:1
+    };
+    const vilidateRules = {
+        required: '${label}不能为空!',
+        types: {
+            email: '${label} is not a valid email!',
+            number: '${label} is not a valid number!',
+        },
+    };
+
+    //获取菜单数据,type:组织0角色1
+    function getTreeData(){
+        xPost(api.getUserMenuResourceTree,{type:1}).then((res)=>{
+            if(res.data.code===200){
+                const data = res.data.data;
+                const treeDatas = structureTreeData(data);
+                setTreeDatas(treeDatas);
+                setTabDatas([treeDatas[0]]);
+                setActiveTab(treeDatas[0].key);
+            }
+
+        })
+    }
+    //数据转换为树形结构所需字段
+    function structureTreeData(data){
+        const arr = [];
+        let obj={};
+        data.map((it,i)=>{
+            obj =JSON.stringify(it.children).replace(/softwareMenuId/g,"key").replace(/menuName/g,'title');
+            arr[i]={
+                title:it.softwareName,
+                key:it.softwareId,
+                children:JSON.parse(obj)
+            }
+        });
+        setSysCheckeds(arr[0]?[arr[0].key]:[]);
+        //form.setFieldsValue({softwares:[{id:arr[0]?[arr[0].key]:''}]});   //默认选中第一个
+        return arr;
+    }
+    useEffect(()=>{
+        getTreeData();
+    },[]);
+    function handleCancel(){
+
+    }
+    function handleSave(){
+        form.validateFields([['softwares',0,'id'],['softwares',0,'softwareMenuIds'],['softwares',0,'softwareResourceIds']]).then((res)=>{
+            save(form.getFieldsValue())
+        });
+
+    }
+    //树形结构选中事件
+    function checkTreeEvent(i,idsArr,sourceIds){
+        console.log(32,i,idsArr,sourceIds,activeTab)
+        const formData=form.getFieldsValue();
+        const arr=formData.softwares;
+        arr[i]={
+            id:activeTab,
+            softwareMenuIds:idsArr,
+            softwareResourceIds:sourceIds
+        };
+        form.setFieldsValue({
+            softwares:arr
+        });
+    }
+    function onTabChange(activeTab){
+        setActiveTab(activeTab)
+    }
+    //状态开关
+    function switchStatus(checked){
+        form.setFieldsValue({
+            status:checked?1:0
+        });
+    }
+    //开放系统勾选事件
+    function softwareChange(checkedValue){
+        let arr = [],item;
+        setSysCheckeds(checkedValue);
+        for(let i=0;i<checkedValue.length;i++){
+            item=treeDatas.find((it)=>it.key===checkedValue[i]);
+            if(item){
+                arr.push(item);
+            }
+        }
+        setTabDatas(arr);
+    }
+    return (
+        <>
+        <Form
+            labelCol={{ span: 6 }}
+            wrapperCol={{ span: 16 }}
+            layout="horizontal"
+            validateMessages={vilidateRules}
+            initialValues={initialValues}
+            form={form}
+        >
+            <Form.Item
+                label="角色名称"
+                name='name'
+                rules={[{ required: true},({ getFieldValue }) => ({
+                    validator(_, value) {
+                        if (value.length<51) {
+                            return Promise.resolve();
+                        }
+                        return Promise.reject(new Error('格式错误!'));
+                    },
+                }),]}>
+                <Input placeholder='请输入角色名称'/>
+            </Form.Item>
+            <Form.Item
+                label="角色描述"
+                name='remark'>
+                <Input placeholder='请输入角色描述' />
+            </Form.Item>
+            <Form.Item
+                label="排序"
+                name='orderNo'>
+                <InputNumber placeholder='大于0的整数' min={0}/>
+            </Form.Item>
+            <Form.Item
+                label="开放系统"
+                rules={[{ required: true}]}>
+                <Checkbox.Group value={sysCheckeds} onChange={softwareChange}>
+                {
+                    treeDatas.map((it, i) => {
+                        return (
+                                <Form.Item key={it.key} noStyle>
+                                    <Checkbox key={i} value={it.key}>{it.title}</Checkbox>
+                                </Form.Item>
+                        )
+                    })
+                }
+                </Checkbox.Group>
+            </Form.Item>
+            <Form.Item
+                label="菜单权限"
+                required>
+                <Tabs onChange={onTabChange} type="card">
+                    {
+                        tabDatas.map((it,i)=>{
+                            console.log(0,it,i,tabDatas)
+                            return (
+                                <TabPane tab={it.title} key={i}>
+                                    <Form.Item key={i} name={['softwares', i, 'softwareMenuIds']} noStyle>
+                                        <MenuTree data={it} checkEv={(checkedKeys,sourceIds)=>checkTreeEvent(i,checkedKeys,sourceIds)}/>
+                                    </Form.Item>
+                                    <Form.Item key={i+"a"} hidden={true} name={['softwares', i, 'id']} noStyle>
+                                        <Input/>
+                                    </Form.Item>
+                                    <Form.Item key={i+"b"} hidden={true} name={['softwares', i, 'softwareResourceIds']} noStyle>
+                                        <Input/>
+                                    </Form.Item>
+                                </TabPane>
+                            )
+                        })
+                    }
+                </Tabs>
+            </Form.Item>
+            <Form.Item
+                label="当前状态">
+                <Space>
+                    <Form.Item
+                        name='status'
+                        noStyle>
+                        <Switch checked={form.status} onChange={switchStatus} />
+                    </Form.Item>
+                    <span>启用</span>
+                </Space>
+            </Form.Item>
+        </Form>
+        <div className="button-box">
+            <Button onClick={handleCancel}>取消</Button>
+            <Button onClick={handleSave} type='primary'>保存</Button>
+        </div>
+        </>
+    )
+}
+
+export default AddRole;

+ 31 - 0
src/components/RoleManager/MenuTree.js

@@ -0,0 +1,31 @@
+import { Tree  } from 'antd';
+
+function MenuTree(props){
+    const {data,checkEv} = props;
+
+    //菜单选中事件
+    function onCheck(checkedKeys,e){
+        const {checkedNodes} = e;
+        const sourceIds  = [];
+        checkedNodes.map((it)=>{
+            if(it.softwareResourceId){
+                sourceIds.push(it.softwareResourceId);
+            }
+        });
+        checkEv(checkedKeys,sourceIds)
+    }
+    function onSelect(){
+
+    }
+    const treeData = data?[data]:null;
+    return (
+        <Tree
+            checkable
+            onCheck={onCheck}
+            onSelect={onSelect}
+            treeData={treeData}
+        />
+    )
+}
+
+export default MenuTree;

+ 239 - 1
src/components/RoleManager/index.js

@@ -1,7 +1,245 @@
+import {useEffect,useState} from 'react';
+/*import { useDispatch,useSelector } from 'react-redux'*/
+import { Table,Modal, message, Menu, Breadcrumb, Dropdown, Space, Form, Input, Button, Row, Col, Select } from 'antd';
+import { DownOutlined,PlusOutlined } from '@ant-design/icons';
+import AddRole from './AddRole';
+import './index.less';
+import apiObj from '@api/index';
+import RoleContext from './role-context';
+
+const {post,api,xPost} = apiObj;
+const { Option } = Select;
 function RoleManager(){
+    useEffect(() => {
+        getFilterList();
+        getTableData();
+    },[]);
+
+    const [dataSource, setDataSource] = useState([]);   //列表数据
+    const [roleDetail, setRoleDetail] = useState([]);   //角色详情数据
+    const [statusList,setStatusList] = useState([]);        //状态
+    const [visible,setVisible] = useState(false);   //删除禁用确认弹窗显示
+    const [addVisible,setAddVisible] = useState(false);         //新增页面显示
+    const [confirmLoading, setConfirmLoading] = useState(false);
+    //弹窗类型:1删除 2有用户删除 3禁用 4有用户禁用
+    const [modalType,setModalType] = useState(1);
+    const [operId,setOperId] = useState('');    //当前操作的角色id
+
+    const tipText={
+        1:'确定要删除该角色?',
+        2:'当前角色存在用户,删除后用户将一并被删除',
+        3:'确定要禁用该角色?',
+        4:'当前角色存在用户,禁用后用户将一并被禁用',
+    };
+
+    //获取筛选下拉数据
+    function getFilterList(){
+        post(api.getManagerBoxInfo).then((res)=>{
+            if(res.data.code===200){
+                const data = res.data.data;
+                setStatusList(data[47]);
+            }
+        })
+    }
+    //获取表格数据
+    function getTableData(param={}){
+        post(api.getRolePage,param).then((res)=>{
+            if(res.data.code===200){
+                const data = res.data.data;
+                setDataSource(data);
+            }
 
+        })
+    }
+    //启用/禁用
+    function enable(flag,id) {
+        const param = {roleId:id||operId,status:flag};
+        xPost(api.disableRole,param).then((res)=>{
+            if(res.data.code===200){
+                getTableData();
+                setVisible(false);
+                message.success((flag?'启用':'禁用')+"成功");
+            }else{
+                message.warning(res.data.msg||'操作失败');
+            }
+        }).catch(()=>{
+            message.error("接口出错");
+        });
+    }
+    //删除
+    function onDelete(){
+        const param = {roleId:operId};
+        xPost(api.deleteRole,param).then((res)=>{
+            if(res.data.code===200){
+                getTableData();
+                setVisible(false);
+                message.success("删除成功");
+            }else{
+                message.warning(res.data.msg||'操作失败');
+            }
+        }).catch(()=>{
+            message.error("接口出错");
+        });
+    }
+    //显示弹窗
+    function showModal(type,id){
+        setModalType(type);
+        setOperId(id);
+        setVisible(true);
+    }
+    //弹窗确认事件
+    function handleOk(){
+        if("1,2".indexOf(modalType)>-1){
+            onDelete();
+        }else if("3,4".indexOf(modalType)>-1){
+            enable(0);
+        }
+    }
+    //弹窗取消
+    function handleCancel(){
+        setVisible(false);
+        setAddVisible(false);
+    }
+    //新增角色弹窗
+    function showAddRole(){
+        setAddVisible(true);
+    }
+    function getRoleDetail(id,type){
+        xPost(api.getRoleById,{roleId:id,type}).then((res)=>{
+            if(res.data.code===200){
+                console.log(res.data.data)
+                //setRoleDetail(res.data.data);
+            }else{
+                message.warning(res.data.msg||'获取详情失败')
+            }
+        });
+    }
+    //修改角色
+    function editRole(id,type){
+        getRoleDetail(id,type);
+        setAddVisible(true);
+    }
+    //保存
+    function addRole(formData){
+        console.log('保存参数:',formData);
+        const param = formData;
+        post(api.addRole,param).then((res)=>{
+            if(res.data.code===200){
+                getTableData();
+                setAddVisible(false);
+                message.success("添加成功");
+            }else{
+                message.warning(res.data.msg||'操作失败');
+            }
+        }).catch(()=>{
+            message.error("接口出错");
+        });
+    }
+    function goBack(){
+        setAddVisible(false);
+    }
+    //表格渲染
+    function RenderTable(){
+        const columns = [
+            { title: '角色名称', dataIndex: 'name', key: 'name' },
+            { title: '角色描述', dataIndex: 'remark', key: 'remark' },
+            { title: '状态', dataIndex: 'gmtCreate',  key: 'statusName'},
+            /*{ title: '创建时间', dataIndex: 'gmtCreate', key: 'gmtCreate' },*/
+            { title: '操作', key: 'operation', render: (row) => {
+                    //console.log(21,row)
+                    if(row.rootFlag){
+                        return '-'
+                    }
+                    return (<Space size="middle">
+                        <a onClick={()=>editRole(row.hospitalId,row.type)}>修改</a>
+                        {row.status==='1'?(<a onClick={()=>showModal(row.hasUserFlag||row.hasHospitalFlag?4:3,row.hospitalId)}>禁用</a>):(<a onClick={()=>enable(1,row.hospitalId)}>启用</a>)}
+                        <a onClick={()=>onDelete(row.hospitalId,row.type)}>删除</a>
+                    </Space>) }},
+        ];
+        return (
+            <Table
+                className="components-table-demo-nested"
+                rowKey={record => record.hospitalId}
+                columns={columns}
+                dataSource={dataSource}
+            />
+        )
+    }
+    //筛选项渲染
+    const [form] = Form.useForm();
+    const onFinish = (values: any) => {
+        getTableData(values);
+        console.log('筛选项:',values);
+    };
+    const onReset = () => {
+        form.resetFields();
+        getTableData();
+    };
+    if(addVisible){
+        return (
+            <RoleContext.Provider value={{save:addRole}}>
+                <AddRole back={goBack}/>
+            </RoleContext.Provider>
+        )
+    }
     return (
-        <div>角色管理</div>
+        <div className='container'>
+            <div className="filter-box">
+                <Form form={form} name="control-hooks" onFinish={onFinish}>
+                    <Row gutter={24}>
+                        <Col span={5} key={0}>
+                            <Form.Item name="hospitalName" label="角色名称">
+                                <Input placeholder='角色名称'/>
+                            </Form.Item>
+                        </Col>
+                        <Col span={5} key={2}>
+                            <Form.Item name="status" label="当前状态">
+                                <Select
+                                    allowClear
+                                >
+                                    {statusList.map((item)=>{
+                                        return (
+                                            <Option value={item.name}  key={item.name}>{item.val}</Option>
+                                        )
+                                    })}
+                                </Select>
+                            </Form.Item>
+                        </Col>
+                        <Col span={9} key={3}>
+                            <Form.Item>
+                                <Button type="primary" htmlType="submit">
+                                    查询
+                                </Button>
+                                <Button htmlType="button" onClick={onReset}>
+                                    重置
+                                </Button>
+                            </Form.Item>
+                        </Col>
+                    </Row>
+                </Form>
+            </div>
+            <div className="table">
+                <div className="table-header">
+                    <Breadcrumb>
+                        <Breadcrumb.Item>角色管理</Breadcrumb.Item>
+                    </Breadcrumb>
+                    <Button type="primary" icon={<PlusOutlined />} onClick={()=> showAddRole()}>新增角色</Button>
+                </div>
+                <RenderTable />
+            </div>
+            <Modal
+                title="提示"
+                okText='确定'
+                cancelText='取消'
+                width={400}
+                visible={visible}
+                onOk={handleOk}
+                confirmLoading={confirmLoading}
+                onCancel={handleCancel}
+            >
+                <p>{tipText[modalType]}</p>
+            </Modal>
+        </div>
     )
 }
 

+ 60 - 0
src/components/RoleManager/index.less

@@ -0,0 +1,60 @@
+@import "@common/common.less";
+
+.container{
+  background: #fff;
+  margin:14px ;
+  padding:17px 28px;
+}
+.ant-table-thead > tr > th{
+  background: @table-th-color;
+  color: @text-color;
+  border-bottom: 1px #D8D8D8 solid;
+}
+.ant-steps-item-title{
+  font-size: 14px;
+}
+.ant-tabs > .ant-tabs-nav, .ant-tabs > div > .ant-tabs-nav{
+  margin-bottom: 0;
+}
+.ant-tabs-content-holder{
+  border: 1px solid #f0f0f0;
+  border-top: none;
+}
+.steps-content{
+  margin-top:40px ;
+}
+.button-box{
+  text-align: right;
+  .ant-btn-primary{
+    margin-left: 20px;
+  }
+}
+.filter-box{
+  .ant-btn-primary{
+    margin-right: 20px;
+  }
+}
+.add-container{
+  margin: 30px 165px;
+}
+.ant-breadcrumb{
+  .back-icon{
+    width: 14px;
+    height: 12px;
+    vertical-align: baseline;
+    margin-right: 4px;
+    cursor: pointer;
+  }
+}
+
+
+.table-header{
+  display: flex;
+  justify-content: space-between;
+  padding: 24px 0;
+  .ant-breadcrumb-link{
+    font-size: 16px;
+    font-weight: 500;
+    color: #333333;
+  }
+}

+ 4 - 0
src/components/RoleManager/role-context.js

@@ -0,0 +1,4 @@
+import {createContext} from 'react';
+const RoleContext = createContext(null);
+
+export default RoleContext;