|   | 
| import React, { useState, useRef, useEffect } from 'react';  | 
| import { Button, message, Modal, Tag } from 'antd';  | 
| import {  | 
|     FooterToolbar,  | 
|     PageContainer,  | 
|     ProTable,  | 
|     LightFilter,  | 
| } from '@ant-design/pro-components';  | 
| import { PlusOutlined, ExportOutlined } from '@ant-design/icons';  | 
| import { FormattedMessage, useIntl } from '@umijs/max';  | 
| import Http from '@/utils/http';  | 
| import Edit from './components/edit'  | 
| import Scope from './components/scope'  | 
| import { TextFilter, SelectFilter, DatetimeRangeFilter, LinkFilter } from '@/components/TableSearch'  | 
| import { statusMap } from '@/utils/enum-util'  | 
| import { repairBug } from '@/utils/common-util';  | 
|   | 
| const TABLE_KEY = "pro-table-role";  | 
|   | 
| const handleSave = async (val, intl) => {  | 
|     const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '正在添加' }));  | 
|     try {  | 
|         const resp = await Http.doPost('api/role/save', val);  | 
|         if (resp.code === 200) {  | 
|             message.success(intl.formatMessage({ id: 'page.add.success', defaultMessage: '添加成功' }));  | 
|             return true;  | 
|         } else {  | 
|             message.error(resp.msg);  | 
|             return false;  | 
|         }  | 
|     } catch (error) {  | 
|         message.error(intl.formatMessage({ id: 'page.add.fail', defaultMessage: '添加失败请重试!' }));  | 
|         return false;  | 
|     } finally {  | 
|         hide();  | 
|     }  | 
| };  | 
|   | 
| const handleUpdate = async (val, intl) => {  | 
|     const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '正在更新' }));  | 
|     try {  | 
|         const resp = await Http.doPost('api/role/update', val);  | 
|         if (resp.code === 200) {  | 
|             message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '更新成功' }));  | 
|             return true;  | 
|         } else {  | 
|             message.error(resp.msg);  | 
|             return false;  | 
|         }  | 
|     } catch (error) {  | 
|         message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '更新失败请重试!' }));  | 
|         return false;  | 
|     } finally {  | 
|         hide();  | 
|     }  | 
| };  | 
|   | 
| const handleRemove = async (rows, intl) => {  | 
|     if (!rows) return true;  | 
|     const hide = message.loading(intl.formatMessage({ id: 'page.deleting', defaultMessage: '正在删除' }));  | 
|     try {  | 
|         const resp = await Http.doPost('api/role/remove/' + rows.map((row) => row.id).join(','));  | 
|         if (resp.code === 200) {  | 
|             message.success(intl.formatMessage({ id: 'page.delete.success', defaultMessage: '删除成功' }));  | 
|             return true;  | 
|         } else {  | 
|             message.error(resp.msg);  | 
|             return false;  | 
|         }  | 
|     } catch (error) {  | 
|         message.error(intl.formatMessage({ id: 'page.delete.fail', defaultMessage: '删除失败,请重试!' }));  | 
|         return false;  | 
|     } finally {  | 
|         hide();  | 
|     }  | 
| };  | 
|   | 
| const handleExport = async (intl) => {  | 
|     const hide = message.loading(intl.formatMessage({ id: 'page.exporting', defaultMessage: '正在导出' }));  | 
|     try {  | 
|         const resp = await Http.doPostBlob('api/role/export');  | 
|         const blob = new Blob([resp], { type: 'application/vnd.ms-excel' });  | 
|         window.location.href = window.URL.createObjectURL(blob);  | 
|         message.success(intl.formatMessage({ id: 'page.export.success', defaultMessage: '导出成功' }));  | 
|         return true;  | 
|     } catch (error) {  | 
|         message.error(intl.formatMessage({ id: 'page.export.fail', defaultMessage: '导出失败,请重试' }));  | 
|         return false;  | 
|     } finally {  | 
|         hide();  | 
|     }  | 
| };  | 
|   | 
| const handleScope = async (val, intl) => {  | 
|     const hide = message.loading(intl.formatMessage({ id: 'page.assigning', defaultMessage: '正在分配' }));  | 
|     try {  | 
|         const resp = await Http.doPost('api/role/scope/update', val);  | 
|         if (resp.code === 200) {  | 
|             message.success(intl.formatMessage({ id: 'page.assign.success', defaultMessage: '分配成功' }));  | 
|             return true;  | 
|         } else {  | 
|             message.error(resp.msg);  | 
|             return false;  | 
|         }  | 
|     } catch (error) {  | 
|         message.error(intl.formatMessage({ id: 'page.assign.fail', defaultMessage: '分配失败请重试!' }));  | 
|         return false;  | 
|     } finally {  | 
|         hide();  | 
|     }  | 
| };  | 
|   | 
| const Main = () => {  | 
|     const intl = useIntl();  | 
|     const formTableRef = useRef();  | 
|     const actionRef = useRef();  | 
|     const [selectedRows, setSelectedRows] = useState([]);  | 
|     const [modalVisible, setModalVisible] = useState(false);  | 
|     const [currentRow, setCurrentRow] = useState();  | 
|     const [searchParam, setSearchParam] = useState({});  | 
|   | 
|     const [scopeModalVisible, setScopeModalVisible] = useState(false);  | 
|     const [menuIds, setMenuIds] = useState([]);  | 
|   | 
|     useEffect(() => {  | 
|   | 
|     }, []);  | 
|   | 
|     const columns = [  | 
|         {  | 
|             title: intl.formatMessage({  | 
|                 id: 'page.table.no',  | 
|                 defaultMessage: 'No'  | 
|             }),  | 
|             dataIndex: 'index',  | 
|             valueType: 'indexBorder',  | 
|             width: 60,  | 
|         },  | 
|         {  | 
|             title: '姓名',  | 
|             dataIndex: 'name',  | 
|             valueType: 'text',  | 
|             filterDropdown: (props) => <TextFilter  | 
|                 name='name'  | 
|                 {...props}  | 
|                 actionRef={actionRef}  | 
|                 setSearchParam={setSearchParam}  | 
|             />,  | 
|             render: (_, record) => {  | 
|                 return (  | 
|                     <a  | 
|                         onClick={() => {  | 
|                             Http.doGetPromise('/api/role/scope/list', { roleId: record.id }, (res) => {  | 
|                                 if (res.data) {  | 
|                                     setMenuIds(res.data);  | 
|                                 }  | 
|                                 setScopeModalVisible(true);  | 
|                                 setCurrentRow(record);  | 
|                             });  | 
|                         }}  | 
|                     >  | 
|                         {_}  | 
|                     </a>  | 
|                 );  | 
|             },  | 
|         },  | 
|         {  | 
|             title: '标识',  | 
|             dataIndex: 'code',  | 
|             valueType: 'text',  | 
|             copyable: true,  | 
|             filterDropdown: (props) => <TextFilter  | 
|                 name='code'  | 
|                 {...props}  | 
|                 actionRef={actionRef}  | 
|                 setSearchParam={setSearchParam}  | 
|             />,  | 
|         },  | 
|         {  | 
|             title: '修改时间',  | 
|             dataIndex: 'updateTime$',  | 
|             valueType: 'text',  | 
|             filterDropdown: (props) => <DatetimeRangeFilter  | 
|                 name='updateTime'  | 
|                 {...props}  | 
|                 actionRef={actionRef}  | 
|                 setSearchParam={setSearchParam}  | 
|             />,  | 
|         },  | 
|         {  | 
|             title: '状态',  | 
|             dataIndex: 'status$',  | 
|             valueType: 'text',  | 
|             filterDropdown: (props) => <SelectFilter  | 
|                 name='status'  | 
|                 {...props}  | 
|                 actionRef={actionRef}  | 
|                 setSearchParam={setSearchParam}  | 
|                 data={[  | 
|                     { label: '正常', value: 1 },  | 
|                     { label: '禁用', value: 0 },  | 
|                 ]}  | 
|             />,  | 
|             render: (_, record) => {  | 
|                 const status = statusMap[record.status]  | 
|                 return <Tag color={status.color}>{status.text}</Tag>  | 
|             },  | 
|         },  | 
|         {  | 
|             title: '备注',  | 
|             dataIndex: 'memo',  | 
|             valueType: 'text',  | 
|             filterDropdown: (props) => <TextFilter  | 
|                 name='memo'  | 
|                 {...props}  | 
|                 actionRef={actionRef}  | 
|                 setSearchParam={setSearchParam}  | 
|             />,  | 
|         },  | 
|         {  | 
|             title: '操作',  | 
|             dataIndex: 'option',  | 
|             width: 260,  | 
|             valueType: 'option',  | 
|             render: (_, record) => [  | 
|                 <Button  | 
|                     type="link"  | 
|                     key="edit"  | 
|                     onClick={() => {  | 
|                         setModalVisible(true);  | 
|                         setCurrentRow(record);  | 
|                     }}  | 
|                 >  | 
|                     <FormattedMessage id='page.edit' defaultMessage='编辑' />  | 
|                 </Button>,  | 
|                 <Button  | 
|                     type="link"  | 
|                     key="scope"  | 
|                     onClick={() => {  | 
|                         Http.doGetPromise('/api/role/scope/list', { roleId: record.id }, (res) => {  | 
|                             if (res.data) {  | 
|                                 setMenuIds(res.data);  | 
|                             }  | 
|                             setScopeModalVisible(true);  | 
|                             setCurrentRow(record);  | 
|                         });  | 
|                     }}  | 
|                 >  | 
|                     <FormattedMessage id='page.assign.permission' defaultMessage='分配权限' />  | 
|                 </Button>,  | 
|                 <Button  | 
|                     type="link"  | 
|                     danger  | 
|                     key="batchRemove"  | 
|                     onClick={async () => {  | 
|                         Modal.confirm({  | 
|                             title: intl.formatMessage({ id: 'page.delete', defaultMessage: '删除' }),  | 
|                             content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '确定删除该项吗?' }),  | 
|                             onOk: async () => {  | 
|                                 const success = await handleRemove([record], intl);  | 
|                                 if (success) {  | 
|                                     if (actionRef.current) {  | 
|                                         actionRef.current.reload();  | 
|                                     }  | 
|                                 }  | 
|                             },  | 
|                         });  | 
|                     }}  | 
|                 >  | 
|                     <FormattedMessage id='page.delete' defaultMessage='删除' />  | 
|                 </Button>,  | 
|             ],  | 
|         },  | 
|     ];  | 
|   | 
|     return (  | 
|         <PageContainer  | 
|             header={{  | 
|                 breadcrumb: {},  | 
|             }}  | 
|         >  | 
|             <div style={{ width: '100%', float: 'right' }}>  | 
|                 <ProTable  | 
|                     key="role"  | 
|                     rowKey="id"  | 
|                     actionRef={actionRef}  | 
|                     formRef={formTableRef}  | 
|                     columns={columns}  | 
|                     cardBordered  | 
|                     scroll={{ x: 1300 }}  | 
|                     dateFormatter="string"  | 
|                     pagination={{ pageSize: 20 }}  | 
|                     search={false}  | 
|                     toolbar={{  | 
|                         multipleLine: true,  | 
|                         search: {  | 
|                             onSearch: (value) => {  | 
|                                 setSearchParam(prevState => ({  | 
|                                     ...prevState,  | 
|                                     condition: value  | 
|                                 }));  | 
|                                 actionRef.current?.reload();  | 
|                             },  | 
|                         },  | 
|                         filter: (  | 
|                             <LightFilter  | 
|                                 onValuesChange={(val) => {  | 
|                                 }}  | 
|                             >  | 
|                             </LightFilter>  | 
|                         ),  | 
|                         actions: [  | 
|                             <Button  | 
|                                 type="primary"  | 
|                                 key="save"  | 
|                                 onClick={async () => {  | 
|                                     setModalVisible(true)  | 
|                                 }}  | 
|                             >  | 
|                                 <PlusOutlined />  | 
|                                 <FormattedMessage id='page.add' defaultMessage='添加' />  | 
|                             </Button>,  | 
|                             <Button  | 
|                                 key="export"  | 
|                                 onClick={async () => {  | 
|                                     handleExport(intl);  | 
|                                 }}  | 
|                             >  | 
|                                 <ExportOutlined />  | 
|                                 <FormattedMessage id='page.export' defaultMessage='导出' />  | 
|                             </Button>,  | 
|                         ],  | 
|                     }}  | 
|                     request={(params, sorter, filter) =>  | 
|                         Http.doPostPromise('/api/role/page', { ...params, ...searchParam }, (res) => {  | 
|                             return {  | 
|                                 data: res.data.records,  | 
|                                 total: res.data.total,  | 
|                                 success: true,  | 
|                             }  | 
|                         })  | 
|                     }  | 
|                     rowSelection={{  | 
|                         onChange: (ids, rows) => {  | 
|                             setSelectedRows(rows);  | 
|                         }  | 
|                     }}  | 
|                     columnsState={{  | 
|                         persistenceKey: TABLE_KEY,  | 
|                         persistenceType: 'localStorage',  | 
|                         defaultValue: {  | 
|                             memo: { show: repairBug(TABLE_KEY, 'memo', false) },  | 
|                             option: { fixed: 'right', disable: true },  | 
|                         },  | 
|                         onChange(value) {  | 
|                         },  | 
|                     }}  | 
|                 />  | 
|             </div>  | 
|   | 
|             {selectedRows?.length > 0 && (  | 
|                 <FooterToolbar  | 
|                     extra={  | 
|                         <div>  | 
|                             <a style={{ fontWeight: 600 }}>{selectedRows.length}</a>  | 
|                             <FormattedMessage id='page.selected' defaultMessage=' 项已选择' />  | 
|                         </div>  | 
|                     }  | 
|                 >  | 
|                     <Button  | 
|                         key="remove"  | 
|                         danger  | 
|                         onClick={async () => {  | 
|                             Modal.confirm({  | 
|                                 title: intl.formatMessage({ id: 'page.delete', defaultMessage: '删除' }),  | 
|                                 content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '确定删除该项吗?' }),  | 
|                                 onOk: async () => {  | 
|                                     const success = await handleRemove(selectedRows, intl);  | 
|                                     if (success) {  | 
|                                         setSelectedRows([]);  | 
|                                         actionRef.current?.reloadAndRest?.();  | 
|                                     }  | 
|                                 },  | 
|                             });  | 
|                         }}  | 
|                     >  | 
|                         <FormattedMessage id='page.delete.batch' defaultMessage='批量删除' />  | 
|                     </Button>  | 
|                 </FooterToolbar>  | 
|             )}  | 
|   | 
|             <Edit  | 
|                 open={modalVisible}  | 
|                 values={currentRow || {}}  | 
|                 onCancel={  | 
|                     () => {  | 
|                         setModalVisible(false);  | 
|                         setCurrentRow(undefined);  | 
|                     }  | 
|                 }  | 
|                 onSubmit={async (values) => {  | 
|                     let ok = false;  | 
|                     if (values.id) {  | 
|                         ok = await handleUpdate({ ...values }, intl)  | 
|                     } else {  | 
|                         ok = await handleSave({ ...values }, intl)  | 
|                     }  | 
|                     if (ok) {  | 
|                         setModalVisible(false);  | 
|                         setCurrentRow(undefined);  | 
|                         if (actionRef.current) {  | 
|                             actionRef.current.reload();  | 
|                         }  | 
|                     }  | 
|                 }  | 
|                 }  | 
|             />  | 
|   | 
|             <Scope  | 
|                 open={scopeModalVisible}  | 
|                 values={currentRow || {}}  | 
|                 originMenuIds={menuIds}  | 
|                 onCancel={  | 
|                     () => {  | 
|                         setScopeModalVisible(false);  | 
|                         setCurrentRow(undefined);  | 
|                         setMenuIds([]);  | 
|                     }  | 
|                 }  | 
|                 onSubmit={async (values) => {  | 
|                     let ok = false;  | 
|                     if (values.id) {  | 
|                         ok = await handleScope({ ...values }, intl)  | 
|                     }  | 
|                     if (ok) {  | 
|                         setScopeModalVisible(false);  | 
|                         setCurrentRow(undefined);  | 
|                         setMenuIds([]);  | 
|                         if (actionRef.current) {  | 
|                             actionRef.current.reload();  | 
|                         }  | 
|                     }  | 
|                 }}  | 
|             />  | 
|         </PageContainer>  | 
|     );  | 
| };  | 
|   | 
| export default Main;  |