|
@ -1,33 +1,89 @@ |
|
|
import { ActionType, PageContainer, ProColumns, ProTable,BetaSchemaForm } from '@ant-design/pro-components' |
|
|
|
|
|
|
|
|
import { |
|
|
|
|
|
ActionType, |
|
|
|
|
|
PageContainer, |
|
|
|
|
|
ProColumns, |
|
|
|
|
|
ProTable, |
|
|
|
|
|
BetaSchemaForm, |
|
|
|
|
|
} from '@ant-design/pro-components' |
|
|
import { createLazyFileRoute } from '@tanstack/react-router' |
|
|
import { createLazyFileRoute } from '@tanstack/react-router' |
|
|
import { useStyle } from './style.ts' |
|
|
import { useStyle } from './style.ts' |
|
|
import { useMemo, useRef, useState } from 'react' |
|
|
|
|
|
import { useAtom, useAtomValue } from 'jotai' |
|
|
|
|
|
import { roleAtom, rolesAtom } from './store.ts' |
|
|
|
|
|
|
|
|
import { useEffect, useMemo, useRef, useState } from 'react' |
|
|
|
|
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai' |
|
|
|
|
|
import { pageAtom, roleAtom, rolesAtom, saveOrUpdateRoleAtom, searchAtom } from './store.ts' |
|
|
import { useTranslation } from '@/i18n.ts' |
|
|
import { useTranslation } from '@/i18n.ts' |
|
|
import { Button, Form, Space, Table } from 'antd' |
|
|
|
|
|
|
|
|
import { Button, Form, Space, Spin, Table, Tree } from 'antd' |
|
|
import { PlusOutlined } from '@ant-design/icons' |
|
|
import { PlusOutlined } from '@ant-design/icons' |
|
|
|
|
|
import { menuDataAtom } from '@/pages/system/menus/store.ts' |
|
|
|
|
|
import { getTreeCheckedStatus } from '@/utils/tree.ts' |
|
|
|
|
|
|
|
|
|
|
|
const MenuTree = (props: any) => { |
|
|
|
|
|
const { data: menuList, isLoading: menuLoading } = useAtomValue(menuDataAtom) |
|
|
|
|
|
const { value, onChange, form, id, mode } = props |
|
|
|
|
|
|
|
|
|
|
|
const onCheck = (checkedKeys: any, info: any) => { |
|
|
|
|
|
if (onChange) { |
|
|
|
|
|
onChange([ ...checkedKeys, ...info.halfCheckedKeys ]) |
|
|
|
|
|
} else { |
|
|
|
|
|
form.setFieldsValue({ [id]: [ ...checkedKeys, ...info.halfCheckedKeys ] }) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (menuLoading) { |
|
|
|
|
|
return <Spin spinning={true} size={'small'}/> |
|
|
|
|
|
} |
|
|
|
|
|
return <Tree treeData={menuList} |
|
|
|
|
|
fieldNames={{ title: 'title', key: 'id' }} |
|
|
|
|
|
disabled={mode !== 'edit'} checkable={true} onCheck={onCheck} |
|
|
|
|
|
checkedKeys={getTreeCheckedStatus(menuList, value)}/> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const Roles = () => { |
|
|
const Roles = () => { |
|
|
|
|
|
|
|
|
const { t } = useTranslation() |
|
|
const { t } = useTranslation() |
|
|
const { styles } = useStyle() |
|
|
const { styles } = useStyle() |
|
|
const [form] = Form.useForm() |
|
|
|
|
|
|
|
|
const [ form ] = Form.useForm() |
|
|
const actionRef = useRef<ActionType>() |
|
|
const actionRef = useRef<ActionType>() |
|
|
const { data, isLoading } = useAtomValue(rolesAtom) |
|
|
|
|
|
const [ role, setRole ] = useAtom(roleAtom) |
|
|
|
|
|
const [ open, setOpen] = useState(false) |
|
|
|
|
|
|
|
|
const [ page, setPage ] = useAtom(pageAtom) |
|
|
|
|
|
const setSearch = useSetAtom(searchAtom) |
|
|
|
|
|
const { data, isLoading, isFetching, refetch } = useAtomValue(rolesAtom) |
|
|
|
|
|
const { isPending, mutate, isSuccess } = useAtomValue(saveOrUpdateRoleAtom) |
|
|
|
|
|
const [ , setRole ] = useAtom(roleAtom) |
|
|
|
|
|
const [ open, setOpen ] = useState(false) |
|
|
|
|
|
|
|
|
const columns = useMemo(() => { |
|
|
const columns = useMemo(() => { |
|
|
|
|
|
|
|
|
return [ |
|
|
return [ |
|
|
{ title: 'id', dataIndex: 'id', hideInTable: true, hideInSearch: true, hideInForm: true,}, |
|
|
|
|
|
{ title: '名称', dataIndex: 'name', valueType: 'text',}, |
|
|
|
|
|
{ title: '别名', dataIndex: 'code', valueType: 'text', }, |
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
title: 'id', dataIndex: 'id', |
|
|
|
|
|
hideInTable: true, |
|
|
|
|
|
hideInSearch: true, |
|
|
|
|
|
// hideInForm: true,
|
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '名称', dataIndex: 'name', valueType: 'text', |
|
|
|
|
|
formItemProps: { |
|
|
|
|
|
rules: [ { required: true, message: '请输入角色名称' } ] |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '别名', dataIndex: 'code', valueType: 'text', |
|
|
|
|
|
formItemProps: { |
|
|
|
|
|
rules: [ { required: true, message: '请输入别名' } ] |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
{ title: '状态', dataIndex: 'status', valueType: 'switch', }, |
|
|
{ title: '状态', dataIndex: 'status', valueType: 'switch', }, |
|
|
{ title: '排序', dataIndex: 'sort', valueType: 'indexBorder', }, |
|
|
|
|
|
{ title: '备注', dataIndex: 'remark' ,valueType: 'textarea' }, |
|
|
|
|
|
{ title: '权限', dataIndex: 'permissions', valueType: 'treeSelect', }, |
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
title: '排序', dataIndex: 'sort', valueType: 'digit', |
|
|
|
|
|
}, |
|
|
|
|
|
{ title: '备注', dataIndex: 'description', valueType: 'textarea' }, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '权限', dataIndex: 'menu_ids', |
|
|
|
|
|
valueType: 'text', |
|
|
|
|
|
renderFormItem: (item, config, form) => { |
|
|
|
|
|
return <MenuTree {...config} form={form} {...item.fieldProps} /> |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
{ |
|
|
{ |
|
|
title: '操作', valueType: 'option', |
|
|
title: '操作', valueType: 'option', |
|
|
key: 'option', |
|
|
key: 'option', |
|
@ -35,7 +91,6 @@ const Roles = () => { |
|
|
<a |
|
|
<a |
|
|
key="editable" |
|
|
key="editable" |
|
|
onClick={() => { |
|
|
onClick={() => { |
|
|
// action?.startEditable?.(record.id)
|
|
|
|
|
|
setRole(record) |
|
|
setRole(record) |
|
|
setOpen(true) |
|
|
setOpen(true) |
|
|
form.setFieldsValue(record) |
|
|
form.setFieldsValue(record) |
|
@ -51,6 +106,12 @@ const Roles = () => { |
|
|
] as ProColumns[] |
|
|
] as ProColumns[] |
|
|
}, []) |
|
|
}, []) |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
if (isSuccess) { |
|
|
|
|
|
setOpen(false) |
|
|
|
|
|
} |
|
|
|
|
|
}, [ isSuccess ]) |
|
|
|
|
|
|
|
|
return ( |
|
|
return ( |
|
|
<PageContainer breadcrumbRender={false} title={false} className={styles.container}> |
|
|
<PageContainer breadcrumbRender={false} title={false} className={styles.container}> |
|
|
<ProTable |
|
|
<ProTable |
|
@ -58,35 +119,40 @@ const Roles = () => { |
|
|
actionRef={actionRef} |
|
|
actionRef={actionRef} |
|
|
headerTitle={t('system.roles.title', '角色管理')} |
|
|
headerTitle={t('system.roles.title', '角色管理')} |
|
|
columns={columns} |
|
|
columns={columns} |
|
|
loading={isLoading} |
|
|
|
|
|
|
|
|
loading={isLoading || isFetching} |
|
|
dataSource={data?.rows} |
|
|
dataSource={data?.rows} |
|
|
search={false} |
|
|
search={false} |
|
|
rowSelection={{ |
|
|
rowSelection={{ |
|
|
selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT], |
|
|
|
|
|
|
|
|
selections: [ Table.SELECTION_ALL, Table.SELECTION_INVERT ], |
|
|
}} |
|
|
}} |
|
|
tableAlertOptionRender={() => { |
|
|
tableAlertOptionRender={() => { |
|
|
return ( |
|
|
return ( |
|
|
<Space size={16}> |
|
|
<Space size={16}> |
|
|
<a>批量删除</a> |
|
|
<a>批量删除</a> |
|
|
</Space> |
|
|
</Space> |
|
|
); |
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
}} |
|
|
|
|
|
options={{ |
|
|
|
|
|
reload: () => { |
|
|
|
|
|
refetch() |
|
|
|
|
|
}, |
|
|
}} |
|
|
}} |
|
|
toolbar={{ |
|
|
toolbar={{ |
|
|
search: { |
|
|
search: { |
|
|
onSearch: (value: string) => { |
|
|
onSearch: (value: string) => { |
|
|
alert(value) |
|
|
|
|
|
|
|
|
setSearch({ name: value }) |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
onSearch: (value) => { |
|
|
|
|
|
console.log('value', value) |
|
|
|
|
|
}, |
|
|
|
|
|
actions: [ |
|
|
actions: [ |
|
|
|
|
|
|
|
|
<Button |
|
|
<Button |
|
|
key="button" |
|
|
key="button" |
|
|
icon={<PlusOutlined/>} |
|
|
icon={<PlusOutlined/>} |
|
|
onClick={() => { |
|
|
onClick={() => { |
|
|
actionRef.current?.reload() |
|
|
|
|
|
|
|
|
form.resetFields() |
|
|
|
|
|
form.setFieldsValue({ |
|
|
|
|
|
id: 0, |
|
|
|
|
|
}) |
|
|
|
|
|
setOpen(true) |
|
|
}} |
|
|
}} |
|
|
type="primary" |
|
|
type="primary" |
|
|
> |
|
|
> |
|
@ -96,10 +162,13 @@ const Roles = () => { |
|
|
}} |
|
|
}} |
|
|
pagination={{ |
|
|
pagination={{ |
|
|
total: data?.total, |
|
|
total: data?.total, |
|
|
current: data?.page, |
|
|
|
|
|
pageSize: data?.pageSize, |
|
|
|
|
|
|
|
|
current: page.page, |
|
|
|
|
|
pageSize: page.pageSize, |
|
|
onChange: (page) => { |
|
|
onChange: (page) => { |
|
|
console.log('page', page) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setPage((prev) => { |
|
|
|
|
|
return { ...prev, page } |
|
|
|
|
|
}) |
|
|
} |
|
|
} |
|
|
}} |
|
|
}} |
|
|
/> |
|
|
/> |
|
@ -117,10 +186,14 @@ const Roles = () => { |
|
|
maskClosable: false, |
|
|
maskClosable: false, |
|
|
}} |
|
|
}} |
|
|
onOpenChange={(open) => { |
|
|
onOpenChange={(open) => { |
|
|
console.log('open', open) |
|
|
|
|
|
setOpen(open) |
|
|
setOpen(open) |
|
|
}} |
|
|
}} |
|
|
columns={columns} /> |
|
|
|
|
|
|
|
|
loading={isPending} |
|
|
|
|
|
onFinish={(values) => { |
|
|
|
|
|
// console.log('values', values)
|
|
|
|
|
|
return mutate(values) |
|
|
|
|
|
}} |
|
|
|
|
|
columns={columns}/> |
|
|
</PageContainer> |
|
|
</PageContainer> |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|