import React from 'react' import Icon from '@ant-design/icons' import { COLOR_ERROR_SECONDARY, COLOR_FONT_SECONDARY, COLOR_PRODUCTION, DATABASE_DELETE_SUCCESS, DATABASE_DUPLICATE_KEY, DATABASE_INSERT_SUCCESS, DATABASE_SELECT_SUCCESS, DATABASE_UPDATE_SUCCESS } from '@/constants/common.constants' import { utcToLocalTime, powerListToPowerTree } from '@/utils/common' import { r_sys_role_add, r_sys_role_change_status, r_sys_power_get_list, r_sys_role_get, r_sys_role_update, r_sys_role_delete, r_sys_role_delete_list } from '@/services/system' import FitFullScreen from '@/components/common/FitFullScreen' import HideScrollbar from '@/components/common/HideScrollbar' import FlexBox from '@/components/common/FlexBox' import Card from '@/components/common/Card' const Role: React.FC = () => { const [modal, contextHolder] = AntdModal.useModal() const [form] = AntdForm.useForm() const formValues = AntdForm.useWatch([], form) const [newFormValues, setNewFormValues] = useState() const [roleData, setRoleData] = useState([]) const [isLoading, setIsLoading] = useState(false) const [tableParams, setTableParams] = useState({ pagination: { current: 1, pageSize: 20, position: ['bottomCenter'] } }) const [searchName, setSearchName] = useState('') const [isUseRegex, setIsUseRegex] = useState(false) const [isRegexLegal, setIsRegexLegal] = useState(true) const [isDrawerOpen, setIsDrawerOpen] = useState(false) const [isDrawerEdit, setIsDrawerEdit] = useState(false) const [submittable, setSubmittable] = useState(false) const [powerTreeData, setPowerTreeData] = useState<_DataNode[]>([]) const [isLoadingPower, setIsLoadingPower] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const [tableSelectedItem, setTableSelectedItem] = useState([]) const dataColumns: _ColumnsType = [ { title: '名称', dataIndex: 'name', width: '15%' }, { title: '权限', dataIndex: 'tree', render: (value: _DataNode[]) => value.length ? : }, { title: '创建时间', dataIndex: 'createTime', width: '10%', align: 'center', render: (value: string) => utcToLocalTime(value) }, { title: '修改时间', dataIndex: 'updateTime', width: '10%', align: 'center', render: (value: string) => utcToLocalTime(value) }, { title: '状态', dataIndex: 'enable', width: '5%', align: 'center', render: (value) => value ? 启用 : 禁用 }, { title: '操作', dataIndex: 'enable', width: '15em', align: 'center', render: (value, record) => ( <> {value ? ( 禁用 ) : ( 启用 )} 编辑 删除 ) } ] const handleOnTableChange = ( pagination: _TablePaginationConfig, filters: Record, sorter: _SorterResult | _SorterResult[] ) => { if (Array.isArray(sorter)) { setTableParams({ pagination, filters, sortField: sorter.map((value) => value.field).join(',') }) } else { setTableParams({ pagination, filters, sortField: sorter.field, sortOrder: sorter.order }) } if (pagination.pageSize !== tableParams.pagination?.pageSize) { setRoleData([]) } } const handleOnTableSelectChange = (selectedRowKeys: React.Key[]) => { setTableSelectedItem(selectedRowKeys) } const handleOnAddBtnClick = () => { setIsDrawerEdit(false) setIsDrawerOpen(true) form.setFieldValue('id', undefined) form.setFieldValue('name', newFormValues?.name) form.setFieldValue('powerIds', newFormValues?.powerIds) form.setFieldValue('enable', newFormValues?.enable ?? true) } const handleOnListDeleteBtnClick = () => { modal .confirm({ title: '确定删除', content: `确定删除选中的 ${tableSelectedItem.length} 个角色吗?` }) .then( (confirmed) => { if (confirmed) { setIsLoading(true) void r_sys_role_delete_list(tableSelectedItem) .then((res) => { const data = res.data if (data.code === DATABASE_DELETE_SUCCESS) { void message.success('删除成功') setTimeout(() => { getRole() }) } else { void message.error('删除失败,请稍后重试') } }) .finally(() => { setIsLoading(false) }) } }, () => {} ) } const handleOnEditBtnClick = (value: RoleWithPowerGetVo) => { return () => { setIsDrawerEdit(true) setIsDrawerOpen(true) form.setFieldValue('id', value.id) form.setFieldValue('name', value.name) form.setFieldValue( 'powerIds', value.operations.map((operation) => operation.id) ) form.setFieldValue('enable', value.enable) void form.validateFields() } } const handleOnDeleteBtnClick = (value: RoleWithPowerGetVo) => { return () => { modal .confirm({ title: '确定删除', content: `确定删除角色 ${value.name} 吗?` }) .then( (confirmed) => { if (confirmed) { setIsLoading(true) void r_sys_role_delete(value.id) .then((res) => { const data = res.data if (data.code === DATABASE_DELETE_SUCCESS) { void message.success('删除成功') setTimeout(() => { getRole() }) } else { void message.error('删除失败,请稍后重试') } }) .finally(() => { setIsLoading(false) }) } }, () => {} ) } } const handleOnDrawerClose = () => { setIsDrawerOpen(false) } const handleOnSubmit = () => { if (isSubmitting) { return } setIsSubmitting(true) if (isDrawerEdit) { void r_sys_role_update(formValues) .then((res) => { const data = res.data switch (data.code) { case DATABASE_UPDATE_SUCCESS: setIsDrawerOpen(false) void message.success('更新成功') getRole() break case DATABASE_DUPLICATE_KEY: void message.error('已存在相同名称的角色') break default: void message.error('更新失败,请稍后重试') } }) .finally(() => { setIsSubmitting(false) }) } else { void r_sys_role_add(formValues) .then((res) => { const data = res.data switch (data.code) { case DATABASE_INSERT_SUCCESS: setIsDrawerOpen(false) void message.success('添加成功') setNewFormValues(undefined) getRole() break case DATABASE_DUPLICATE_KEY: void message.error('已存在相同名称的角色') break default: void message.error('添加失败,请稍后重试') } }) .finally(() => { setIsSubmitting(false) }) } } const handleOnSearchNameChange = (e: React.ChangeEvent) => { setSearchName(e.target.value) if (isUseRegex) { try { RegExp(e.target.value) setIsRegexLegal(!(e.target.value.includes('{}') || e.target.value.includes('[]'))) } catch (e) { setIsRegexLegal(false) } } else { setIsRegexLegal(true) } } const handleOnSearchNameKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { getRole() } } const handleOnUseRegexChange = (e: _CheckboxChangeEvent) => { setIsUseRegex(e.target.checked) if (e.target.checked) { try { RegExp(searchName) setIsRegexLegal(!(searchName.includes('{}') || searchName.includes('[]'))) } catch (e) { setIsRegexLegal(false) } } else { setIsRegexLegal(true) } } const handleOnQueryBtnClick = () => { getRole() } const handleOnChangStatusBtnClick = (id: string, newStatus: boolean) => { return () => { if (isLoading) { return } setIsLoading(true) void r_sys_role_change_status({ id, enable: newStatus }) .then((res) => { const data = res.data if (data.code === DATABASE_UPDATE_SUCCESS) { void message.success('更新成功') setTimeout(() => { getRole() }) } else { void message.error('更新失败,请稍后重试') } }) .finally(() => { setIsLoading(false) }) } } const getRole = () => { if (isLoading) { return } if (!isRegexLegal) { void message.error('非法正则表达式') return } setIsLoading(true) void r_sys_role_get({ currentPage: tableParams.pagination?.current, pageSize: tableParams.pagination?.pageSize, sortField: tableParams.sortField && tableParams.sortOrder ? (tableParams.sortField as string) : undefined, sortOrder: tableParams.sortField && tableParams.sortOrder ? tableParams.sortOrder : undefined, searchName: searchName.trim().length ? searchName : undefined, searchRegex: isUseRegex ? isUseRegex : undefined, ...tableParams.filters }) .then((res) => { const data = res.data if (data.code === DATABASE_SELECT_SUCCESS) { const records = data.data?.records records?.map((value) => { value.tree = powerListToPowerTree( value.modules, value.menus, value.elements, value.operations ) return value }) records && setRoleData(records) data.data && setTableParams({ ...tableParams, pagination: { ...tableParams.pagination, total: data.data.total } }) } else { void message.error('获取失败,请稍后重试') } }) .finally(() => { setIsLoading(false) }) } const getPowerTreeData = () => { if (isLoadingPower) { return } setIsLoadingPower(true) void r_sys_power_get_list() .then((res) => { const data = res.data if (data.code === DATABASE_SELECT_SUCCESS) { const powerSet = data.data powerSet && setPowerTreeData( powerListToPowerTree( powerSet.moduleList, powerSet.menuList, powerSet.elementList, powerSet.operationList ) ) } else { void message.error('获取权限列表失败,请稍后重试') } }) .finally(() => { setIsLoadingPower(false) }) } useEffect(() => { form.validateFields({ validateOnly: true }).then( () => { setSubmittable(true) }, () => { setSubmittable(false) } ) if (!isDrawerEdit && formValues) { setNewFormValues({ name: formValues.name, powerIds: formValues.powerIds, enable: formValues.enable }) } }, [formValues]) useEffect(() => { getPowerTreeData() }, []) useEffect(() => { getRole() }, [ JSON.stringify(tableParams.filters), JSON.stringify(tableParams.sortField), JSON.stringify(tableParams.sortOrder), JSON.stringify(tableParams.pagination?.pageSize), JSON.stringify(tableParams.pagination?.current) ]) const toolbar = ( 名称 } suffix={ <> {!isRegexLegal ? ( 非法表达式 ) : undefined} .* } allowClear value={searchName} onChange={handleOnSearchNameChange} onKeyDown={handleOnSearchNameKeyDown} status={isRegexLegal ? undefined : 'error'} /> 查询 ) const table = ( record.id} pagination={tableParams.pagination} loading={isLoading} onChange={handleOnTableChange} rowSelection={{ type: 'checkbox', onChange: handleOnTableSelectChange }} /> ) const drawerToolbar = ( 取消 提交 ) const addAndEditForm = ( ) return ( <> {toolbar} {table} {addAndEditForm} {contextHolder} ) } export default Role